Update vendored deps

This commit is contained in:
Luke Street 2022-05-09 00:19:04 -04:00
parent 77346105a8
commit 71969bda5f
1516 changed files with 325348 additions and 292586 deletions

View File

@ -255,11 +255,11 @@ if(TINT_IS_SUBPROJECT)
set(TINT_BUILD_DOCS_DEFAULT OFF)
set(TINT_BUILD_TESTS_DEFAULT OFF)
else()
set(TINT_BUILD_DOCS_DEFAULT ON)
set(TINT_BUILD_TESTS_DEFAULT ON)
set(TINT_BUILD_DOCS_DEFAULT OFF)
set(TINT_BUILD_TESTS_DEFAULT OFF)
endif()
option_if_not_defined(TINT_BUILD_SAMPLES "Build samples" ON)
option_if_not_defined(TINT_BUILD_SAMPLES "Build samples" OFF)
option_if_not_defined(TINT_BUILD_DOCS "Build documentation" ${TINT_BUILD_DOCS_DEFAULT})
option_if_not_defined(TINT_DOCS_WARN_AS_ERROR "When building documentation, treat warnings as errors" OFF)
option_if_not_defined(TINT_BUILD_SPV_READER "Build the SPIR-V input reader" ON)

View File

@ -8,22 +8,25 @@ rm -rf build
rm -rf buildtools
rm -rf testing
rm -rf third_party/angle
rm -rf third_party/benchmark
rm -rf third_party/catapult
rm -rf third_party/googletest
rm -rf third_party/gpuweb-cts
rm -rf third_party/llvm-build
rm -rf third_party/markupsafe
rm -rf third_party/protobuf
rm -rf third_party/swiftshader
rm -rf third_party/vulkan_memory_allocator
rm -rf third_party/vulkan-deps/glslang
rm -rf third_party/vulkan-deps/spirv-cross
rm -rf third_party/vulkan-deps/vulkan-headers
rm -rf third_party/vulkan-deps/vulkan-loader
rm -rf third_party/vulkan-deps/vulkan-tools
rm -rf third_party/vulkan-deps/vulkan-validation-layers
rm -rf third_party/webgpu-cts
rm -rf third_party/zlib
# Ensure vulkan-deps are committed
rm third_party/vulkan-deps/.gitignore
rm -f third_party/vulkan-deps/.gitignore
# Remove gitmodules, some third_party/ repositories contain these and leaving them around would
# cause any recursive submodule clones to fail because e.g. some reference internal Google
@ -37,7 +40,6 @@ find third_party -depth -type d -name .git -exec rm -rf {} \;
find third_party -depth -type d -name tests -print -exec rm -rf {} \;
find third_party -depth -type d -name docs -print -exec rm -rf {} \;
find third_party -depth -type d -name samples -print -exec rm -rf {} \;
rm -rf third_party/tint/test/
rm -rf third_party/swiftshader/third_party/SPIRV-Tools # already in third_party/vulkan-deps/spirv-tools
rm -rf third_party/swiftshader/third_party/SPIRV-Headers # already in third_party/vulkan-deps/spirv-headers

230
third_party/abseil-cpp/BUILD.gn vendored Normal file
View File

@ -0,0 +1,230 @@
# Copyright (c) 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Flags specified here must not impact ABI. Code compiled with and without these
# opts will be linked together, and in some cases headers compiled with and
# without these options will be part of the same program.
import("//build/config/c++/c++.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build/toolchain/toolchain.gni")
import("//build_overrides/build.gni")
import("//third_party/abseil-cpp/absl.gni")
config("absl_component_build") {
defines = [ "ABSL_CONSUME_DLL" ]
}
component("absl") {
public_deps = [ ":absl_component_deps" ]
if (is_component_build) {
public_configs = [ ":absl_component_build" ]
if (is_win && is_clang) {
if (current_cpu == "x64") {
if (is_debug) {
sources = [ "symbols_x64_dbg.def" ]
} else {
if (is_asan) {
sources = [ "symbols_x64_rel_asan.def" ]
} else {
sources = [ "symbols_x64_rel.def" ]
}
}
}
if (current_cpu == "x86") {
if (is_debug) {
sources = [ "symbols_x86_dbg.def" ]
} else {
sources = [ "symbols_x86_rel.def" ]
}
}
if (current_cpu == "arm64") {
if (is_debug) {
sources = [ "symbols_arm64_dbg.def" ]
} else {
sources = [ "symbols_arm64_rel.def" ]
}
}
}
}
}
group("absl_component_deps") {
public_deps = [
"//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/container:btree",
"//third_party/abseil-cpp/absl/container:fixed_array",
"//third_party/abseil-cpp/absl/container:flat_hash_map",
"//third_party/abseil-cpp/absl/container:flat_hash_set",
"//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/container:node_hash_map",
"//third_party/abseil-cpp/absl/container:node_hash_set",
"//third_party/abseil-cpp/absl/debugging:failure_signal_handler",
"//third_party/abseil-cpp/absl/debugging:stacktrace",
"//third_party/abseil-cpp/absl/debugging:symbolize",
"//third_party/abseil-cpp/absl/functional:bind_front",
"//third_party/abseil-cpp/absl/hash",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/numeric:int128",
"//third_party/abseil-cpp/absl/status",
"//third_party/abseil-cpp/absl/status:statusor",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:str_format",
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/abseil-cpp/absl/time",
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:span",
"//third_party/abseil-cpp/absl/types:variant",
]
# The following dependencies currently don't build with NaCl.
# TODO(https://crbug.com/1114625): Fix build errors and remove this section.
if (is_nacl) {
public_deps -= [
"//third_party/abseil-cpp/absl/container:flat_hash_map",
"//third_party/abseil-cpp/absl/container:flat_hash_set",
"//third_party/abseil-cpp/absl/container:node_hash_map",
"//third_party/abseil-cpp/absl/container:node_hash_set",
"//third_party/abseil-cpp/absl/debugging:failure_signal_handler",
]
}
visibility = [ ":absl" ]
}
group("default") {
deps = [
"absl/types:any",
"absl/types:bad_any_cast",
"absl/types:bad_optional_access",
"absl/types:optional",
"absl/types:span",
]
}
config("absl_include_config") {
include_dirs = [ "." ]
}
config("absl_define_config") {
defines = [ "ABSL_ALLOCATOR_NOTHROW=1" ]
if (is_win && !use_custom_libcxx) {
defines += [
# See crbug.com/1101367: Acknowledge extended alignment when using
# MSVC's standard library.
"_ENABLE_EXTENDED_ALIGNED_STORAGE",
]
}
}
config("absl_default_cflags_cc") {
cflags_cc = []
if (is_clang) {
cflags_cc += [
# TODO(crbug.com/588506): Explicitly enable conversion warnings.
"-Wbool-conversion",
"-Wconstant-conversion",
"-Wenum-conversion",
"-Wint-conversion",
"-Wliteral-conversion",
"-Wnon-literal-null-conversion",
"-Wnull-conversion",
"-Wobjc-literal-conversion",
"-Wno-sign-conversion",
"-Wstring-conversion",
]
if (!is_nacl && !use_xcode_clang) {
cflags_cc += [ "-Wbitfield-enum-conversion" ]
}
}
if (is_win) {
cflags_cc += [
"/wd4005", # macro-redefinition
"/wd4018", # sign-compare
"/wd4068", # unknown pragma
"/wd4702", # unreachable code
]
}
}
config("absl_test_cflags_cc") {
cflags_cc = []
if (is_clang || !is_win) {
cflags_cc += [
"-Wno-conversion-null",
"-Wno-missing-declarations",
"-Wno-sign-compare",
"-Wno-unused-function",
"-Wno-unused-parameter",
"-Wno-unused-private-field",
]
}
if (is_win) {
cflags_cc += [
"/wd4018", # signed/unsigned mismatch
"/wd4101", # unreferenced local variable
]
}
}
if (build_with_chromium) {
import("//testing/test.gni")
if (!is_component_build) {
test("absl_tests") {
testonly = true
deps = [
"absl/algorithm:algorithm_test",
"absl/algorithm:container_test",
"absl/base:config_test",
"absl/cleanup:cleanup_test",
"absl/container:inlined_vector_test",
"absl/hash:low_level_hash_test",
"absl/memory:memory_test",
"absl/meta:type_traits_test",
"absl/status:statusor_test",
"absl/strings:ascii_test",
"absl/strings:cord_rep_btree_test",
"absl/strings:cord_rep_btree_reader_test",
"absl/strings:cord_rep_consume_test",
"absl/strings:cordz_functions_test",
"absl/strings:cordz_info_statistics_test",
"absl/strings:cordz_info_test",
"absl/strings:cordz_test",
"absl/strings:cordz_update_scope_test",
"absl/strings:cord_rep_btree_navigator_test",
"absl/strings:cordz_update_tracker_test",
"absl/strings:match_test",
"absl/strings:str_replace_test",
"absl/strings:string_view_test",
"absl/types:optional_test",
"absl/types:variant_test",
"//third_party/googletest:gtest_main",
]
}
}
test("absl_hardening_tests") {
testonly = true
sources = [ "absl_hardening_test.cc" ]
deps = [
"//base/test:run_all_unittests",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/container:fixed_array",
"//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:span",
"//third_party/abseil-cpp/absl/types:variant",
"//third_party/googletest:gtest",
]
}
}

81
third_party/abseil-cpp/absl.gni vendored Normal file
View File

@ -0,0 +1,81 @@
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# This file contains the definition of the template absl_source_set which
# should be the only type of target needed in abseil's BUILD.gn files.
# This template will correctly set "configs" and "public_configs" in order
# to correctly compile abseil in Chromium.
#
# Usage:
# Most of the times its usage will be similar to the example below but all
# the arguments avilable in source_set are also available for absl_source_set.
#
# absl_source_set("foo") {
# sources = [ "foo.cc" ]
# public = [ "foo.h" ]
# deps = [ ":bar" ]
# }
import("//build_overrides/build.gni")
template("absl_source_set") {
source_set(target_name) {
forward_variables_from(invoker, "*")
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
"//third_party/abseil-cpp:absl_default_cflags_cc",
"//third_party/abseil-cpp:absl_define_config",
]
if (is_component_build) {
defines = [ "ABSL_BUILD_DLL" ]
if (!is_win) {
configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
configs += [ "//build/config/gcc:symbol_visibility_default" ]
}
}
if (!defined(public_configs)) {
public_configs = []
}
public_configs += [ "//third_party/abseil-cpp:absl_include_config" ]
if (!defined(visibility)) {
# Within Chromium builds, restrict direct visibility of Abseil sources, so
# users must depend on //third_party/abseil-cpp:absl. This prevents use of
# banned targets like absl/types:any. A few targets require exceptions.
# TODO(crbug.com/1096380): Consider replacing build_with_chromium with
# is_component_build for a narrower, more accurate condition.
if (build_with_chromium) {
visibility = [
# Abseil itself.
"//third_party/abseil-cpp/*",
# GTest. It unconditionally #includes any.h if pretty-print support
# for absl types is enabled.
"//third_party/googletest/*",
# WebRTC binary to run PSNR and SSIM video quality analysis. It
# statically links absl and it is used by "browser_tests" when
# is_component_build=false but it cannot depend on the absl
# component because it uses absl/flags.
"//third_party/webrtc/rtc_tools:frame_analyzer",
# WebRTC binaries used by //:chromium_builder_asan. They both
# statically link absl (because they depend on absl/flags) and are
# used by Chromium only when is_component_build=false.
"//third_party/webrtc/rtc_tools:rtp_generator",
"//third_party/webrtc/rtc_tools:video_replay",
# Not used by Chromium directly.
"//chromecast/internal/*",
"//libassistant/*",
]
} else {
visibility = [ "*" ]
}
}
}
}

View File

@ -0,0 +1,43 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("algorithm") {
public = [ "algorithm.h" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("container") {
public = [ "container.h" ]
deps = [
":algorithm",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}
absl_source_set("algorithm_test") {
testonly = true
sources = [ "algorithm_test.cc" ]
deps = [
":algorithm",
"//third_party/googletest:gtest",
"//third_party/googletest:gmock",
]
}
absl_source_set("container_test") {
testonly = true
sources = [ "container_test.cc" ]
deps = [
":container",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/types:span",
"//third_party/googletest:gtest",
"//third_party/googletest:gmock",
]
}

View File

@ -0,0 +1,293 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("atomic_hook") {
public = [ "internal/atomic_hook.h" ]
public_deps = [
":config",
":core_headers",
]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("errno_saver") {
public = [ "internal/errno_saver.h" ]
public_deps = [ ":config" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("log_severity") {
sources = [ "log_severity.cc" ]
public = [ "log_severity.h" ]
public_deps = [
":config",
":core_headers",
]
}
absl_source_set("raw_logging_internal") {
sources = [ "internal/raw_logging.cc" ]
public = [ "internal/raw_logging.h" ]
public_deps = [
":atomic_hook",
":config",
":core_headers",
":log_severity",
]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("spinlock_wait") {
sources = [
"internal/spinlock_akaros.inc",
"internal/spinlock_linux.inc",
"internal/spinlock_posix.inc",
"internal/spinlock_wait.cc",
"internal/spinlock_win32.inc",
]
public = [ "internal/spinlock_wait.h" ]
deps = [
":base_internal",
":core_headers",
":errno_saver",
]
visibility = [ "//third_party/abseil-cpp/absl/base:*" ]
}
absl_source_set("config") {
public = [
"config.h",
"options.h",
"policy_checks.h",
]
}
absl_source_set("dynamic_annotations") {
public = [ "dynamic_annotations.h" ]
# Abseil's dynamic annotations are only visible inside Abseil because
# their usage is deprecated in Chromium (see README.chromium for more info).
visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":config",
":core_headers",
]
}
absl_source_set("core_headers") {
public = [
"attributes.h",
"const_init.h",
"macros.h",
"optimization.h",
"port.h",
"thread_annotations.h",
]
public_deps = [ ":config" ]
}
absl_source_set("malloc_internal") {
sources = [ "internal/low_level_alloc.cc" ]
public = [
"internal/direct_mmap.h",
"internal/low_level_alloc.h",
]
public_deps = [
":base",
":base_internal",
":config",
":core_headers",
":dynamic_annotations",
":raw_logging_internal",
]
}
absl_source_set("base_internal") {
public = [
"internal/hide_ptr.h",
"internal/identity.h",
"internal/inline_variable.h",
"internal/invoke.h",
"internal/scheduling_mode.h",
]
public_deps = [
":config",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("base") {
sources = [
"internal/cycleclock.cc",
"internal/spinlock.cc",
"internal/sysinfo.cc",
"internal/thread_identity.cc",
"internal/unscaledcycleclock.cc",
]
public = [
"call_once.h",
"casts.h",
"internal/cycleclock.h",
"internal/low_level_scheduling.h",
"internal/per_thread_tls.h",
"internal/spinlock.h",
"internal/sysinfo.h",
"internal/thread_identity.h",
"internal/tsan_mutex_interface.h",
"internal/unscaledcycleclock.h",
]
# TODO(mbonadei): The bazel file has:
# "-DEFAULTLIB:advapi32.lib"
# understand if this is needed here as well.
public_deps = [
":atomic_hook",
":base_internal",
":config",
":core_headers",
":dynamic_annotations",
":log_severity",
":raw_logging_internal",
":spinlock_wait",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}
absl_source_set("throw_delegate") {
sources = [ "internal/throw_delegate.cc" ]
public = [ "internal/throw_delegate.h" ]
public_deps = [
":config",
":raw_logging_internal",
]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("exception_testing") {
testonly = true
public = [ "internal/exception_testing.h" ]
public_deps = [ ":config" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("pretty_function") {
public = [ "internal/pretty_function.h" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
# TODO(mbonadei): This target throws by design. We should probably
# just remove it.
# source_set("exception_safety_testing") {
# testonly = true
# configs -= [ "//build/config/compiler:chromium_code" ]
# configs += [
# "//build/config/compiler:no_chromium_code",
# "//third_party/abseil-cpp:absl_test_cflags_cc",
# ]
# public_configs = [ "//third_party/abseil-cpp:absl_include_config" ]
# sources = [
# "internal/exception_safety_testing.cc",
# ]
# public = [
# "internal/exception_safety_testing.h",
# ]
# deps = [
# ":config",
# ":pretty_function",
# "//third_party/abseil-cpp/absl/memory",
# "//third_party/abseil-cpp/absl/meta:type_traits",
# "//third_party/abseil-cpp/absl/strings",
# "//third_party/abseil-cpp/absl/utility",
# "//third_party/googletest:gtest",
# ]
# }
absl_source_set("spinlock_test_common") {
testonly = true
sources = [ "spinlock_test_common.cc" ]
deps = [
":base",
":base_internal",
":config",
":core_headers",
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/googletest:gtest",
]
}
absl_source_set("endian") {
public = [
"internal/endian.h",
"internal/unaligned_access.h",
]
public_deps = [
":base",
":config",
":core_headers",
]
}
absl_source_set("exponential_biased") {
sources = [ "internal/exponential_biased.cc" ]
public = [ "internal/exponential_biased.h" ]
public_deps = [
":config",
":core_headers",
]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("periodic_sampler") {
sources = [ "internal/periodic_sampler.cc" ]
public = [ "internal/periodic_sampler.h" ]
public_deps = [
":core_headers",
":exponential_biased",
]
}
absl_source_set("scoped_set_env") {
testonly = true
public = [ "internal/scoped_set_env.h" ]
sources = [ "internal/scoped_set_env.cc" ]
public_deps = [
":config",
]
deps = [
":raw_logging_internal",
]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("strerror") {
sources = [ "internal/strerror.cc" ]
public = [ "internal/strerror.h" ]
public_deps = [
":config",
]
deps = [
":core_headers",
":errno_saver",
]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("fast_type_id") {
public = [ "internal/fast_type_id.h" ]
public_deps = [ ":config" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("config_test") {
testonly = true
sources = [ "config_test.cc" ]
deps = [
":config",
"//third_party/abseil-cpp/absl/synchronization:thread_pool",
"//third_party/googletest:gtest",
]
}

View File

@ -0,0 +1,35 @@
# Copyright 2021 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("cleanup_internal") {
public = [ "internal/cleanup.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/utility",
]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("cleanup") {
public = [ "cleanup.h" ]
deps = [
":cleanup_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
}
absl_source_set("cleanup_test") {
testonly = true
sources = [ "cleanup_test.cc" ]
deps = [
":cleanup",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/utility",
"//third_party/googletest:gtest",
]
}

View File

@ -0,0 +1,375 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("compressed_tuple") {
public = [ "internal/compressed_tuple.h" ]
deps = [ "//third_party/abseil-cpp/absl/utility" ]
}
absl_source_set("fixed_array") {
public = [ "fixed_array.h" ]
deps = [
":compressed_tuple",
"//third_party/abseil-cpp/absl/algorithm",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:dynamic_annotations",
"//third_party/abseil-cpp/absl/base:throw_delegate",
"//third_party/abseil-cpp/absl/memory",
]
}
absl_source_set("inlined_vector_internal") {
public = [ "internal/inlined_vector.h" ]
deps = [
":compressed_tuple",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/types:span",
]
}
absl_source_set("inlined_vector") {
public = [ "inlined_vector.h" ]
deps = [
":inlined_vector_internal",
"//third_party/abseil-cpp/absl/algorithm",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:throw_delegate",
"//third_party/abseil-cpp/absl/memory",
]
}
absl_source_set("counting_allocator") {
testonly = true
public = [ "internal/counting_allocator.h" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
visibility = [ ":*" ]
}
absl_source_set("test_instance_tracker") {
testonly = true
sources = [ "internal/test_instance_tracker.cc" ]
public = [ "internal/test_instance_tracker.h" ]
deps = [ "//third_party/abseil-cpp/absl/types:compare" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("flat_hash_map") {
public = [ "flat_hash_map.h" ]
deps = [
":container_memory",
":hash_function_defaults",
":raw_hash_map",
"//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/memory",
]
}
absl_source_set("flat_hash_set") {
public = [ "flat_hash_set.h" ]
deps = [
":container_memory",
":hash_function_defaults",
":raw_hash_set",
"//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/memory",
]
}
absl_source_set("node_hash_map") {
public = [ "node_hash_map.h" ]
deps = [
":container_memory",
":hash_function_defaults",
":node_hash_policy",
":raw_hash_map",
"//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/memory",
]
}
absl_source_set("node_hash_set") {
public = [ "node_hash_set.h" ]
deps = [
":container_memory",
":hash_function_defaults",
":node_hash_policy",
":raw_hash_set",
"//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/memory",
]
}
absl_source_set("container_memory") {
public = [ "internal/container_memory.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("hash_function_defaults") {
public = [ "internal/hash_function_defaults.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/hash",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:cord",
]
}
absl_source_set("hash_generator_testing") {
testonly = true
sources = [ "internal/hash_generator_testing.cc" ]
public = [ "internal/hash_generator_testing.h" ]
deps = [
":hash_policy_testing",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/strings",
]
}
absl_source_set("hash_policy_testing") {
testonly = true
public = [ "internal/hash_policy_testing.h" ]
deps = [
"//third_party/abseil-cpp/absl/hash",
"//third_party/abseil-cpp/absl/strings",
]
}
absl_source_set("hash_policy_traits") {
public = [ "internal/hash_policy_traits.h" ]
deps = [ "//third_party/abseil-cpp/absl/meta:type_traits" ]
}
absl_source_set("hashtable_debug") {
public = [ "internal/hashtable_debug.h" ]
deps = [ ":hashtable_debug_hooks" ]
}
absl_source_set("hashtable_debug_hooks") {
public = [ "internal/hashtable_debug_hooks.h" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("hashtablez_sampler") {
public = [ "internal/hashtablez_sampler.h" ]
sources = [
"internal/hashtablez_sampler.cc",
"internal/hashtablez_sampler_force_weak_definition.cc",
]
deps = [
":have_sse",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:exponential_biased",
"//third_party/abseil-cpp/absl/debugging:stacktrace",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("node_hash_policy") {
public = [ "internal/node_hash_policy.h" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("raw_hash_map") {
public = [ "internal/raw_hash_map.h" ]
deps = [
":container_memory",
":raw_hash_set",
"//third_party/abseil-cpp/absl/base:throw_delegate",
]
}
absl_source_set("have_sse") {
public = [ "internal/have_sse.h" ]
visibility = [ ":*" ]
}
absl_source_set("common") {
public = [ "internal/common.h" ]
deps = [
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/types:optional",
]
}
absl_source_set("raw_hash_set") {
sources = [ "internal/raw_hash_set.cc" ]
public = [ "internal/raw_hash_set.h" ]
deps = [
":common",
":compressed_tuple",
":container_memory",
":hash_policy_traits",
":hashtable_debug_hooks",
":hashtablez_sampler",
":have_sse",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("layout") {
public = [ "internal/layout.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:span",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("tracked") {
testonly = true
public = [ "internal/tracked.h" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("unordered_map_constructor_test") {
testonly = true
public = [ "internal/unordered_map_constructor_test.h" ]
deps = [
":hash_generator_testing",
":hash_policy_testing",
"//third_party/googletest:gtest",
]
}
absl_source_set("unordered_map_lookup_test") {
testonly = true
public = [ "internal/unordered_map_lookup_test.h" ]
deps = [
":hash_generator_testing",
":hash_policy_testing",
"//third_party/googletest:gtest",
]
}
absl_source_set("unordered_map_modifiers_test") {
testonly = true
public = [ "internal/unordered_map_modifiers_test.h" ]
deps = [
":hash_generator_testing",
":hash_policy_testing",
"//third_party/googletest:gtest",
]
}
absl_source_set("unordered_set_constructor_test") {
testonly = true
public = [ "internal/unordered_set_constructor_test.h" ]
deps = [
":hash_generator_testing",
":hash_policy_testing",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/googletest:gtest",
]
}
absl_source_set("unordered_set_members_test") {
testonly = true
public = [ "internal/unordered_set_members_test.h" ]
deps = [
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/googletest:gtest",
]
}
absl_source_set("unordered_map_members_test") {
testonly = true
public = [ "internal/unordered_map_members_test.h" ]
deps = [
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/googletest:gtest",
]
}
absl_source_set("unordered_set_lookup_test") {
testonly = true
public = [ "internal/unordered_set_lookup_test.h" ]
deps = [
":hash_generator_testing",
":hash_policy_testing",
"//third_party/googletest:gtest",
]
}
absl_source_set("unordered_set_modifiers_test") {
testonly = true
public = [ "internal/unordered_set_modifiers_test.h" ]
deps = [
":hash_generator_testing",
":hash_policy_testing",
"//third_party/googletest:gtest",
]
}
absl_source_set("btree") {
sources = [
"internal/btree.h",
"internal/btree_container.h",
]
public = [
"btree_map.h",
"btree_set.h",
]
deps = [
":common",
":compressed_tuple",
":container_memory",
":layout",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:throw_delegate",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:cord",
"//third_party/abseil-cpp/absl/types:compare",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("inlined_vector_test") {
testonly = true
sources = [ "inlined_vector_test.cc" ]
if (is_win && !is_clang) {
cflags_cc = [ "/wd4996" ]
} else {
cflags_cc = [ "-Wno-deprecated-declarations" ]
}
deps = [
":counting_allocator",
":inlined_vector",
":test_instance_tracker",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:exception_testing",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/hash:hash_testing",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/strings",
"//third_party/googletest:gtest",
"//third_party/googletest:gmock",
]
}

View File

@ -0,0 +1,171 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/sanitizers/sanitizers.gni")
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("stacktrace") {
sources = [
"internal/stacktrace_aarch64-inl.inc",
"internal/stacktrace_arm-inl.inc",
"internal/stacktrace_config.h",
"internal/stacktrace_emscripten-inl.inc",
"internal/stacktrace_generic-inl.inc",
"internal/stacktrace_powerpc-inl.inc",
"internal/stacktrace_riscv-inl.inc",
"internal/stacktrace_unimplemented-inl.inc",
"internal/stacktrace_win32-inl.inc",
"internal/stacktrace_x86-inl.inc",
"stacktrace.cc",
]
public = [ "stacktrace.h" ]
deps = [
":debugging_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
}
absl_source_set("symbolize") {
sources = [
"symbolize.cc",
"symbolize_darwin.inc",
"symbolize_elf.inc",
"symbolize_emscripten.inc",
"symbolize_unimplemented.inc",
"symbolize_win32.inc",
]
public = [
"internal/symbolize.h",
"symbolize.h",
]
deps = [
":debugging_internal",
":demangle_internal",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:dynamic_annotations",
"//third_party/abseil-cpp/absl/base:malloc_internal",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/strings",
]
# TODO(mbonadei): The bazel file has:
# -DEFAULTLIB:dbghelp.lib
# evaluate if this needs to be added here as well.
}
absl_source_set("examine_stack") {
sources = [ "internal/examine_stack.cc" ]
public = [ "internal/examine_stack.h" ]
visibility = [ ":*" ]
deps = [
":stacktrace",
":symbolize",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
}
absl_source_set("failure_signal_handler") {
sources = [ "failure_signal_handler.cc" ]
public = [ "failure_signal_handler.h" ]
deps = [
":examine_stack",
":stacktrace",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:errno_saver",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
}
absl_source_set("debugging_internal") {
sources = [
"internal/address_is_readable.cc",
"internal/elf_mem_image.cc",
"internal/vdso_support.cc",
]
public = [
"internal/address_is_readable.h",
"internal/elf_mem_image.h",
"internal/vdso_support.h",
]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:dynamic_annotations",
"//third_party/abseil-cpp/absl/base:errno_saver",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
}
absl_source_set("demangle_internal") {
sources = [ "internal/demangle.cc" ]
public = [ "internal/demangle.h" ]
deps = [
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
}
absl_source_set("leak_check") {
if (is_ios || is_win) {
sources = []
public = []
} else {
sources = [ "leak_check.cc" ]
public = [ "leak_check.h" ]
}
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
}
absl_source_set("leak_check_disable") {
sources = [ "leak_check_disable.cc" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
if (is_lsan) {
absl_source_set("leak_check_api_enabled_for_testing") {
testonly = true
sources = [ "leak_check.cc" ]
public = [ "leak_check.h" ]
visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
}
} else {
absl_source_set("leak_check_api_disabled_for_testing") {
testonly = true
sources = [ "leak_check.cc" ]
public = [ "leak_check.h" ]
visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
}
}
absl_source_set("stack_consumption") {
testonly = true
sources = [ "internal/stack_consumption.cc" ]
public = [ "internal/stack_consumption.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
visibility = [ ":*" ]
}

View File

@ -0,0 +1,215 @@
# Copyright 2019 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("path_util") {
public = [ "internal/path_util.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/strings",
]
visibility = [ ":*" ]
}
absl_source_set("program_name") {
sources = [ "internal/program_name.cc" ]
public = [ "internal/program_name.h" ]
deps = [
":path_util",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/synchronization",
]
visibility = [ ":*" ]
}
# Since absl/flags are only used by some test binaries (e.g. in WebRTC),
# there is no need to strip flags from mobile platforms binaries.
# This does not affect Chromium.
config("absl_flags_config") {
defines = [ "ABSL_FLAGS_STRIP_NAMES=0" ]
}
absl_source_set("config") {
sources = [ "usage_config.cc" ]
public_configs = [ ":absl_flags_config" ]
public = [
"config.h",
"usage_config.h",
]
deps = [
":path_util",
":program_name",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/synchronization",
]
}
absl_source_set("marshalling") {
sources = [ "marshalling.cc" ]
public = [ "marshalling.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:log_severity",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:str_format",
]
}
absl_source_set("commandlineflag_internal") {
public = [ "internal/commandlineflag.h" ]
sources = [ "internal/commandlineflag.cc" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:fast_type_id",
]
}
absl_source_set("commandlineflag") {
sources = [ "commandlineflag.cc" ]
public = [ "commandlineflag.h" ]
deps = [
":commandlineflag_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:fast_type_id",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
]
}
absl_source_set("private_handle_accessor") {
sources = [ "internal/private_handle_accessor.cc" ]
public = [ "internal/private_handle_accessor.h" ]
deps = [
":commandlineflag",
":commandlineflag_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/strings",
]
visibility = [ ":*" ]
}
absl_source_set("reflection") {
sources = [ "reflection.cc" ]
public = [
"internal/registry.h",
"reflection.h",
]
deps = [
":commandlineflag",
":commandlineflag_internal",
":config",
":private_handle_accessor",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/container:flat_hash_map",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/synchronization",
]
}
absl_source_set("flag_internal") {
sources = [ "internal/flag.cc" ]
public = [
"internal/flag.h",
"internal/sequence_lock.h",
]
deps = [
":commandlineflag",
":commandlineflag_internal",
":config",
":marshalling",
":reflection",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/abseil-cpp/absl/utility",
]
visibility = [
":*",
"//third_party/abseil-cpp/absl/base/*",
]
}
absl_source_set("flag") {
sources = [ "flag.cc" ]
public = [
"declare.h",
"flag.h",
]
deps = [
":config",
":flag_internal",
":reflection",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/strings",
]
}
absl_source_set("usage_internal") {
sources = [ "internal/usage.cc" ]
public = [ "internal/usage.h" ]
deps = [
":commandlineflag",
":config",
":flag",
":flag_internal",
":path_util",
":private_handle_accessor",
":program_name",
":reflection",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/container:flat_hash_map",
"//third_party/abseil-cpp/absl/strings",
]
visibility = [ ":*" ]
}
absl_source_set("usage") {
sources = [ "usage.cc" ]
public = [ "usage.h" ]
deps = [
":usage_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/synchronization",
]
}
absl_source_set("parse") {
sources = [ "parse.cc" ]
public = [
"internal/parse.h",
"parse.h",
]
deps = [
":commandlineflag",
":commandlineflag_internal",
":config",
":flag",
":flag_internal",
":private_handle_accessor",
":program_name",
":reflection",
":usage",
":usage_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/synchronization",
]
}

View File

@ -0,0 +1,26 @@
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("bind_front") {
sources = [ "internal/front_binder.h" ]
public = [ "bind_front.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/container:compressed_tuple",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("function_ref") {
sources = [ "internal/function_ref.h" ]
public = [ "function_ref.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}

View File

@ -0,0 +1,84 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build_overrides/build.gni")
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("hash") {
sources = [
"internal/hash.cc",
"internal/hash.h",
]
public = [ "hash.h" ]
deps = [
":city",
":low_level_hash",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/container:fixed_array",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:int128",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:variant",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("hash_testing") {
testonly = true
public = [ "hash_testing.h" ]
deps = [
":spy_hash_state",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:variant",
"//third_party/googletest:gtest",
]
}
absl_source_set("spy_hash_state") {
testonly = true
public = [ "internal/spy_hash_state.h" ]
deps = [
":hash",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:str_format",
]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("city") {
public = [ "internal/city.h" ]
sources = [ "internal/city.cc" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:endian",
]
}
absl_source_set("low_level_hash") {
public = [ "internal/low_level_hash.h" ]
sources = [ "internal/low_level_hash.cc" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/numeric:int128",
]
visibility = [ ":*" ]
}
absl_source_set("low_level_hash_test") {
testonly = true
sources = [ "internal/low_level_hash_test.cc" ]
deps = [
":low_level_hash",
"//third_party/abseil-cpp/absl/strings",
"//third_party/googletest:gtest",
"//third_party/googletest:gmock",
]
}

View File

@ -0,0 +1,29 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("memory") {
public = [ "memory.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}
absl_source_set("memory_test") {
testonly = true
# TODO(https://crbug.com/1116473): memory_test.cc fails to build in
# standalone ANGLE on Windows
if (!build_with_chromium && !is_win) {
sources = [ "memory_test.cc" ]
deps = [
":memory",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
}

View File

@ -0,0 +1,22 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("type_traits") {
public = [ "type_traits.h" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("type_traits_test") {
testonly = true
sources = [ "type_traits_test.cc" ]
if (is_clang) {
cflags_cc = [ "-Wno-unused-private-field" ]
}
deps = [
":type_traits",
"//third_party/googletest:gtest",
]
}

View File

@ -0,0 +1,35 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("bits") {
public = [
"bits.h",
"internal/bits.h",
]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
}
absl_source_set("int128") {
sources = [
"int128.cc",
"int128_have_intrinsic.inc",
"int128_no_intrinsic.inc",
]
public = [ "int128.h" ]
deps = [
":bits",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
}
absl_source_set("representation") {
public = [ "internal/representation.h" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}

View File

@ -0,0 +1,85 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("random") {
public = [ "random.h" ]
deps = [
":distributions",
":seed_sequences",
"//third_party/abseil-cpp/absl/random/internal:nonsecure_base",
"//third_party/abseil-cpp/absl/random/internal:pcg_engine",
"//third_party/abseil-cpp/absl/random/internal:pool_urbg",
"//third_party/abseil-cpp/absl/random/internal:randen_engine",
]
}
absl_source_set("distributions") {
public = [
"bernoulli_distribution.h",
"beta_distribution.h",
"discrete_distribution.h",
"distributions.h",
"exponential_distribution.h",
"gaussian_distribution.h",
"log_uniform_int_distribution.h",
"poisson_distribution.h",
"uniform_int_distribution.h",
"uniform_real_distribution.h",
"zipf_distribution.h",
]
sources = [
"discrete_distribution.cc",
"gaussian_distribution.cc",
]
deps = [
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/random/internal:distribution_caller",
"//third_party/abseil-cpp/absl/random/internal:fast_uniform_bits",
"//third_party/abseil-cpp/absl/random/internal:fastmath",
"//third_party/abseil-cpp/absl/random/internal:generate_real",
"//third_party/abseil-cpp/absl/random/internal:iostream_state_saver",
"//third_party/abseil-cpp/absl/random/internal:traits",
"//third_party/abseil-cpp/absl/random/internal:uniform_helper",
"//third_party/abseil-cpp/absl/random/internal:wide_multiply",
"//third_party/abseil-cpp/absl/strings",
]
}
absl_source_set("seed_gen_exception") {
public = [ "seed_gen_exception.h" ]
sources = [ "seed_gen_exception.cc" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("seed_sequences") {
public = [ "seed_sequences.h" ]
sources = [ "seed_sequences.cc" ]
deps = [
":seed_gen_exception",
"//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/random/internal:nonsecure_base",
"//third_party/abseil-cpp/absl/random/internal:pool_urbg",
"//third_party/abseil-cpp/absl/random/internal:salted_seed_seq",
"//third_party/abseil-cpp/absl/random/internal:seed_material",
"//third_party/abseil-cpp/absl/types:span",
]
}
absl_source_set("bit_gen_ref") {
public = [ "bit_gen_ref.h" ]
deps = [
":random",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:fast_type_id",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/random/internal:distribution_caller",
"//third_party/abseil-cpp/absl/random/internal:fast_uniform_bits",
]
}

View File

@ -0,0 +1,269 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("traits") {
public = [ "traits.h" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("distribution_caller") {
public = [ "distribution_caller.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:fast_type_id",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("fast_uniform_bits") {
public = [ "fast_uniform_bits.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}
absl_source_set("seed_material") {
public = [ "seed_material.h" ]
sources = [ "seed_material.cc" ]
if (is_win) {
# TODO(mbonadei): In the bazel file this is -DEFAULTLIB:bcrypt.lib.
libs = [ "bcrypt.lib" ]
}
deps = [
":fast_uniform_bits",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:dynamic_annotations",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:span",
]
}
absl_source_set("pool_urbg") {
public = [ "pool_urbg.h" ]
sources = [ "pool_urbg.cc" ]
deps = [
":randen",
":seed_material",
":traits",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/random:seed_gen_exception",
"//third_party/abseil-cpp/absl/types:span",
]
}
absl_source_set("explicit_seed_seq") {
testonly = true
public = [ "explicit_seed_seq.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:endian",
]
}
absl_source_set("sequence_urbg") {
testonly = true
public = [ "sequence_urbg.h" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("salted_seed_seq") {
public = [ "salted_seed_seq.h" ]
deps = [
":seed_material",
"//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:span",
]
}
absl_source_set("iostream_state_saver") {
public = [ "iostream_state_saver.h" ]
deps = [
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:int128",
]
}
absl_source_set("generate_real") {
public = [ "generate_real.h" ]
deps = [
":fastmath",
":traits",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
]
}
absl_source_set("fastmath") {
public = [ "fastmath.h" ]
deps = [ "//third_party/abseil-cpp/absl/numeric:bits" ]
}
absl_source_set("wide_multiply") {
public = [ "wide_multiply.h" ]
deps = [
":traits",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/numeric:int128",
]
}
absl_source_set("nonsecure_base") {
public = [ "nonsecure_base.h" ]
deps = [
":pool_urbg",
":salted_seed_seq",
":seed_material",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:span",
]
}
absl_source_set("pcg_engine") {
public = [ "pcg_engine.h" ]
deps = [
":fastmath",
":iostream_state_saver",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/numeric:int128",
]
}
absl_source_set("randen_engine") {
public = [ "randen_engine.h" ]
deps = [
":iostream_state_saver",
":randen",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}
absl_source_set("platform") {
public = [
"platform.h",
"randen_traits.h",
]
sources = [ "randen_round_keys.cc" ]
deps = [
"//build:chromeos_buildflags",
"//third_party/abseil-cpp/absl/base:config",
]
}
absl_source_set("randen") {
public = [ "randen.h" ]
sources = [ "randen.cc" ]
deps = [
":platform",
":randen_hwaes",
":randen_slow",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
}
absl_source_set("randen_slow") {
public = [ "randen_slow.h" ]
sources = [ "randen_slow.cc" ]
deps = [
":platform",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/numeric:int128",
]
}
absl_source_set("randen_hwaes") {
public = [
"randen_detect.h",
"randen_hwaes.h",
]
sources = [ "randen_detect.cc" ]
deps = [
":platform",
":randen_hwaes_impl",
"//third_party/abseil-cpp/absl/base:config",
]
}
absl_source_set("randen_hwaes_impl") {
sources = [
"randen_hwaes.cc",
"randen_hwaes.h",
]
deps = [
":platform",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/numeric:int128",
]
}
executable("gaussian_distribution_gentables") {
sources = [ "gaussian_distribution_gentables.cc" ]
deps = [
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/random:distributions",
]
}
absl_source_set("distribution_test_util") {
testonly = true
public = [
"chi_square.h",
"distribution_test_util.h",
]
sources = [
"chi_square.cc",
"distribution_test_util.cc",
]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:str_format",
"//third_party/abseil-cpp/absl/types:span",
]
}
# TODO(danilchap): Enable when can be compiled on all chromium bots.
# nanobenchmark uses platform specific functions to take accurate current time,
# and fallbacks to clock_gettime. Several chromium configurations lack both
# dedicated code and the clock_gettime system function.
# absl_source_set("nanobenchmark") {
# sources = [ "nanobenchmark.cc" ]
# deps = [
# ":platform",
# ":randen_engine",
# "//third_party/abseil-cpp/absl/base:config",
# "//third_party/abseil-cpp/absl/base:core_headers",
# "//third_party/abseil-cpp/absl/base:raw_logging_internal",
# ]
# }
absl_source_set("uniform_helper") {
public = [ "uniform_helper.h" ]
deps = [
":traits",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}

View File

@ -0,0 +1,69 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("status") {
public = [
"status.h",
"status_payload_printer.h",
]
sources = [
"internal/status_internal.h",
"status.cc",
"status_payload_printer.cc",
]
deps = [
"//third_party/abseil-cpp/absl/base:atomic_hook",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/debugging:stacktrace",
"//third_party/abseil-cpp/absl/debugging:symbolize",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:cord",
"//third_party/abseil-cpp/absl/strings:str_format",
"//third_party/abseil-cpp/absl/types:optional",
]
}
absl_source_set("statusor") {
public = [
"statusor.h",
]
sources = [
"internal/statusor_internal.h",
"statusor.cc",
]
deps = [
":status",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:variant",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("statusor_test") {
testonly = true
sources = [
"statusor_test.cc",
]
deps = [
":status",
":statusor",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:any",
"//third_party/abseil-cpp/absl/utility",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}

View File

@ -0,0 +1,548 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build_overrides/build.gni")
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("strings") {
sources = [
"ascii.cc",
"charconv.cc",
"escaping.cc",
"internal/charconv_bigint.cc",
"internal/charconv_bigint.h",
"internal/charconv_parse.cc",
"internal/charconv_parse.h",
"internal/memutil.cc",
"internal/memutil.h",
"internal/stl_type_traits.h",
"internal/str_join_internal.h",
"internal/str_split_internal.h",
"match.cc",
"numbers.cc",
"str_cat.cc",
"str_replace.cc",
"str_split.cc",
"string_view.cc",
"substitute.cc",
]
public = [
"ascii.h",
"charconv.h",
"escaping.h",
"internal/string_constant.h",
"match.h",
"numbers.h",
"str_cat.h",
"str_join.h",
"str_replace.h",
"str_split.h",
"string_view.h",
"strip.h",
"substitute.h",
]
deps = [
":internal",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/base:throw_delegate",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/numeric:int128",
]
}
absl_source_set("internal") {
sources = [
"internal/escaping.cc",
"internal/ostringstream.cc",
"internal/utf8.cc",
]
public = [
"internal/char_map.h",
"internal/escaping.h",
"internal/ostringstream.h",
"internal/resize_uninitialized.h",
"internal/utf8.h",
]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}
absl_source_set("str_format") {
public = [ "str_format.h" ]
deps = [ ":str_format_internal" ]
}
absl_source_set("str_format_internal") {
sources = [
"internal/str_format/arg.cc",
"internal/str_format/bind.cc",
"internal/str_format/extension.cc",
"internal/str_format/float_conversion.cc",
"internal/str_format/output.cc",
"internal/str_format/parser.cc",
]
public = [
"internal/str_format/arg.h",
"internal/str_format/bind.h",
"internal/str_format/checker.h",
"internal/str_format/extension.h",
"internal/str_format/float_conversion.h",
"internal/str_format/output.h",
"internal/str_format/parser.h",
]
visibility = [ ":*" ]
deps = [
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/functional:function_ref",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/numeric:int128",
"//third_party/abseil-cpp/absl/numeric:representation",
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:span",
]
}
absl_source_set("cord_internal") {
sources = [
"internal/cord_internal.cc",
"internal/cord_rep_btree.cc",
"internal/cord_rep_btree_navigator.cc",
"internal/cord_rep_btree_reader.cc",
"internal/cord_rep_consume.cc",
"internal/cord_rep_ring.cc",
]
public = [
"internal/cord_internal.h",
"internal/cord_rep_btree.h",
"internal/cord_rep_btree_navigator.h",
"internal/cord_rep_btree_reader.h",
"internal/cord_rep_consume.h",
"internal/cord_rep_flat.h",
"internal/cord_rep_ring.h",
"internal/cord_rep_ring_reader.h",
]
visibility = [ ":*" ]
deps = [
":strings",
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/base:throw_delegate",
"//third_party/abseil-cpp/absl/container:compressed_tuple",
"//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/container:layout",
"//third_party/abseil-cpp/absl/functional:function_ref",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/types:span",
]
}
absl_source_set("cord_rep_btree_test") {
testonly = true
sources = ["internal/cord_rep_btree_test.cc"]
deps = [
":cord_internal",
":cord_rep_test_util",
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/cleanup",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
absl_source_set("cord_rep_btree_reader_test") {
testonly = true
sources = ["internal/cord_rep_btree_reader_test.cc"]
deps = [
":cord",
":cord_internal",
":cord_rep_test_util",
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
absl_source_set("cordz_update_tracker") {
public = ["internal/cordz_update_tracker.h"]
visibility = [ "//third_party/abseil-cpp/*" ]
deps = ["//third_party/abseil-cpp/absl/base:config"]
}
absl_source_set("cordz_update_tracker_test") {
testonly = true
sources = ["internal/cordz_update_tracker_test.cc"]
deps = [
":cordz_update_tracker",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
absl_source_set("cord") {
sources = [ "cord.cc" ]
public = [ "cord.h" ]
deps = [
":cord_internal",
":cordz_functions",
":cordz_info",
":cordz_statistics",
":cordz_update_scope",
":cordz_update_tracker",
":internal",
":str_format",
":strings",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/container:fixed_array",
"//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/functional:function_ref",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/types:optional",
]
}
absl_source_set("cordz_handle") {
sources = ["internal/cordz_handle.cc"]
public = ["internal/cordz_handle.h"]
visibility = [ "//third_party/abseil-cpp/*" ]
deps = [
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/synchronization",
]
}
absl_source_set("cordz_info") {
sources = ["internal/cordz_info.cc"]
public = ["internal/cordz_info.h"]
visibility = [ "//third_party/abseil-cpp/*" ]
deps = [
":cord_internal",
":cordz_functions",
":cordz_handle",
":cordz_statistics",
":cordz_update_tracker",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/debugging:stacktrace",
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/abseil-cpp/absl/types:span",
]
}
absl_source_set("cordz_update_scope") {
public = ["internal/cordz_update_scope.h"]
visibility = [ "//third_party/abseil-cpp/*" ]
deps = [
":cord_internal",
":cordz_info",
":cordz_update_tracker",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
}
absl_source_set("cordz_update_scope_test") {
testonly = true
sources = ["internal/cordz_update_scope_test.cc"]
deps = [
":cord_internal",
":cordz_info",
":cordz_test_helpers",
":cordz_update_scope",
":cordz_update_tracker",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
absl_source_set("cordz_sample_token") {
sources = ["internal/cordz_sample_token.cc"]
public = ["internal/cordz_sample_token.h"]
visibility = [ "//third_party/abseil-cpp/*" ]
deps = [
":cordz_handle",
":cordz_info",
"//third_party/abseil-cpp/absl/base:config",
]
}
absl_source_set("cordz_functions") {
sources = ["internal/cordz_functions.cc"]
public = ["internal/cordz_functions.h"]
visibility = [ "//third_party/abseil-cpp/*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:exponential_biased",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
}
absl_source_set("cordz_statistics") {
public = ["internal/cordz_statistics.h"]
visibility = [ "//third_party/abseil-cpp/*" ]
deps = [
":cordz_update_tracker",
"//third_party/abseil-cpp/absl/base:config",
]
}
absl_source_set("cordz_functions_test") {
testonly = true
sources = [ "internal/cordz_functions_test.cc" ]
deps = [
":cordz_functions",
":cordz_test_helpers",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
# TODO(b/186638384): Re-enable when random is compilable on win32-archive-rel bot
# absl_source_set("cordz_handle_test") {
# testonly = true
# sources = [ "internal/cordz_handle_test.cc" ]
# deps = [
# ":cordz_handle",
# "//third_party/abseil-cpp/absl/base:config",
# "//third_party/abseil-cpp/absl/memory",
# "//third_party/abseil-cpp/absl/random",
# "//third_party/abseil-cpp/absl/random:distributions",
# "//third_party/abseil-cpp/absl/synchronization",
# "//third_party/abseil-cpp/absl/synchronization:thread_pool",
# "//third_party/abseil-cpp/absl/time",
# "//third_party/googletest:gmock",
# "//third_party/googletest:gtest",
# ]
# }
absl_source_set("cordz_info_test") {
testonly = true
sources = [ "internal/cordz_info_test.cc" ]
deps = [
":cord_internal",
":cordz_handle",
":cordz_info",
":cordz_statistics",
":cordz_test_helpers",
":cordz_update_tracker",
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/debugging:stacktrace",
"//third_party/abseil-cpp/absl/debugging:symbolize",
"//third_party/abseil-cpp/absl/types:span",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
absl_source_set("cordz_info_statistics_test") {
testonly = true
sources = [ "internal/cordz_info_statistics_test.cc" ]
deps = [
":cord",
":cord_internal",
":cordz_info",
":cordz_sample_token",
":cordz_statistics",
":cordz_update_scope",
":cordz_update_tracker",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/abseil-cpp/absl/synchronization:thread_pool",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
# TODO(b/186638384): Re-enable when random is compilable on win32-archive-rel bot
# absl_source_set("cordz_sample_token_test") {
# testonly = true
# sources = [ "internal/cordz_sample_token_test.cc" ]
# deps = [
# ":cord_internal",
# ":cordz_handle",
# ":cordz_info",
# ":cordz_sample_token",
# ":cordz_test_helpers",
# "//third_party/abseil-cpp/absl/base:config",
# "//third_party/abseil-cpp/absl/memory",
# "//third_party/abseil-cpp/absl/random",
# "//third_party/abseil-cpp/absl/synchronization",
# "//third_party/abseil-cpp/absl/synchronization:thread_pool",
# "//third_party/abseil-cpp/absl/time",
# "//third_party/googletest:gmock",
# "//third_party/googletest:gtest",
# ]
# }
absl_source_set("cord_test_helpers") {
testonly = true
public = [ "cord_test_helpers.h" ]
deps = [
":cord",
":cord_internal",
":strings",
"//third_party/abseil-cpp/absl/base:config",
]
}
absl_source_set("cord_rep_test_util") {
testonly = true
public = ["internal/cord_rep_test_util.h"]
deps = [
":cord_internal",
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
}
absl_source_set("cordz_test_helpers") {
testonly = true
public = ["cordz_test_helpers.h"]
deps = [
":cord",
":cord_internal",
":cordz_info",
":cordz_sample_token",
":cordz_statistics",
":cordz_update_tracker",
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/googletest:gtest",
]
}
absl_source_set("cordz_test") {
testonly = true
sources = ["cordz_test.cc"]
deps = [
":cord",
":cord_test_helpers",
":cordz_functions",
":cordz_info",
":cordz_sample_token",
":cordz_statistics",
":cordz_test_helpers",
":cordz_update_tracker",
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
absl_source_set("cord_rep_consume_test") {
testonly = true
sources = ["internal/cord_rep_consume_test.cc"]
deps = [
":cord_internal",
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/debugging:leak_check",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
absl_source_set("pow10_helper") {
testonly = true
sources = [ "internal/pow10_helper.cc" ]
public = [ "internal/pow10_helper.h" ]
visibility = [ ":*" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("ascii_test") {
testonly = true
sources = [ "ascii_test.cc" ]
deps = [
":strings",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/googletest:gtest",
]
}
absl_source_set("match_test") {
testonly = true
sources = [ "match_test.cc" ]
deps = [
":strings",
"//third_party/googletest:gtest",
]
}
absl_source_set("str_replace_test") {
testonly = true
sources = [ "str_replace_test.cc" ]
deps = [
":strings",
"//third_party/googletest:gtest",
]
}
absl_source_set("string_view_test") {
testonly = true
sources = [ "string_view_test.cc" ]
deps = [
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:dynamic_annotations",
"//third_party/googletest:gtest",
]
}
absl_source_set("cord_rep_btree_navigator_test") {
testonly = true
sources = [ "internal/cord_rep_btree_navigator_test.cc" ]
deps = [
":cord_internal",
":cord_rep_test_util",
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}

View File

@ -0,0 +1,89 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("graphcycles_internal") {
sources = [ "internal/graphcycles.cc" ]
public = [ "internal/graphcycles.h" ]
deps = [
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:malloc_internal",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("kernel_timeout_internal") {
public = [ "internal/kernel_timeout.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/time",
]
visibility = [ ":*" ]
}
absl_source_set("synchronization") {
sources = [
"barrier.cc",
"blocking_counter.cc",
"internal/create_thread_identity.cc",
"internal/per_thread_sem.cc",
"internal/waiter.cc",
"mutex.cc",
"notification.cc",
]
public = [
"barrier.h",
"blocking_counter.h",
"internal/create_thread_identity.h",
"internal/futex.h",
"internal/per_thread_sem.h",
"internal/waiter.h",
"mutex.h",
"notification.h",
]
deps = [
":graphcycles_internal",
":kernel_timeout_internal",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:atomic_hook",
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:dynamic_annotations",
"//third_party/abseil-cpp/absl/base:malloc_internal",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/debugging:stacktrace",
"//third_party/abseil-cpp/absl/debugging:symbolize",
"//third_party/abseil-cpp/absl/time",
]
}
absl_source_set("thread_pool") {
testonly = true
public = [ "internal/thread_pool.h" ]
deps = [
":synchronization",
"//third_party/abseil-cpp/absl/base:core_headers",
]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("per_thread_sem_test_common") {
testonly = true
sources = [ "internal/per_thread_sem_test.cc" ]
deps = [
":synchronization",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/time",
"//third_party/googletest:gtest",
]
}

View File

@ -0,0 +1,49 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("time") {
sources = [
"civil_time.cc",
"clock.cc",
"duration.cc",
"format.cc",
"internal/get_current_time_chrono.inc",
"internal/get_current_time_posix.inc",
"time.cc",
]
public = [
"civil_time.h",
"clock.h",
"time.h",
]
deps = [
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/numeric:int128",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/time/internal/cctz:civil_time",
"//third_party/abseil-cpp/absl/time/internal/cctz:time_zone",
]
}
absl_source_set("test_util") {
testonly = true
sources = [
"internal/test_util.cc",
"internal/zoneinfo.inc",
]
public = [ "internal/test_util.h" ]
deps = [
":time",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/time/internal/cctz:time_zone",
"//third_party/googletest:gtest",
"//third_party/googletest:gmock",
]
visibility = [ "//third_party/abseil-cpp/absl/time:*" ]
}

View File

@ -0,0 +1,46 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("civil_time") {
sources = [ "src/civil_time_detail.cc" ]
public = [
"include/cctz/civil_time.h",
"include/cctz/civil_time_detail.h",
]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("time_zone") {
sources = [
"src/time_zone_fixed.cc",
"src/time_zone_fixed.h",
"src/time_zone_format.cc",
"src/time_zone_if.cc",
"src/time_zone_if.h",
"src/time_zone_impl.cc",
"src/time_zone_impl.h",
"src/time_zone_info.cc",
"src/time_zone_info.h",
"src/time_zone_libc.cc",
"src/time_zone_libc.h",
"src/time_zone_lookup.cc",
"src/time_zone_posix.cc",
"src/time_zone_posix.h",
"src/tzfile.h",
"src/zone_info_source.cc",
]
public = [
"include/cctz/time_zone.h",
"include/cctz/zone_info_source.h",
]
if (is_apple) {
frameworks = [ "Foundation.framework" ]
}
deps = [
":civil_time",
"//third_party/abseil-cpp/absl/base:config",
]
}

View File

@ -0,0 +1,139 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build_overrides/build.gni")
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("any") {
public = [ "any.h" ]
public_deps = [
":bad_any_cast",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:fast_type_id",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("bad_any_cast") {
public = [ "bad_any_cast.h" ]
deps = [
":bad_any_cast_impl",
]
public_deps = [
"//third_party/abseil-cpp/absl/base:config",
]
}
absl_source_set("bad_any_cast_impl") {
sources = [ "bad_any_cast.cc" ]
public = [ "bad_any_cast.h" ]
public_deps = [
"//third_party/abseil-cpp/absl/base:config",
]
deps = [
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
visibility = [ ":*" ]
}
absl_source_set("span") {
public = [ "span.h" ]
sources = [ "internal/span.h" ]
public_deps = [
"//third_party/abseil-cpp/absl/algorithm",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:throw_delegate",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}
absl_source_set("optional") {
sources = [ "internal/optional.h" ]
public = [ "optional.h" ]
public_deps = [
":bad_optional_access",
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("bad_optional_access") {
sources = [ "bad_optional_access.cc" ]
public = [ "bad_optional_access.h" ]
public_deps = [
"//third_party/abseil-cpp/absl/base:config",
]
deps = [
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
}
absl_source_set("bad_variant_access") {
sources = [ "bad_variant_access.cc" ]
public = [ "bad_variant_access.h" ]
public_deps = [
"//third_party/abseil-cpp/absl/base:config",
]
deps = [
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
}
absl_source_set("variant") {
sources = [ "internal/variant.h" ]
public = [ "variant.h" ]
public_deps = [
":bad_variant_access",
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/utility",
]
}
absl_source_set("compare") {
public = [ "compare.h" ]
public_deps = [
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}
absl_source_set("optional_test") {
testonly = true
sources = [ "optional_test.cc" ]
deps = [
":optional",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/strings",
"//third_party/googletest:gtest",
]
}
absl_source_set("variant_test") {
testonly = true
sources = [ "variant_test.cc" ]
if (is_clang) {
cflags_cc = [ "-Wno-unused-function" ]
}
deps = [
":variant",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/strings",
"//third_party/googletest:gtest",
"//third_party/googletest:gmock",
]
}

View File

@ -0,0 +1,14 @@
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("utility") {
public = [ "utility.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
}

29
third_party/jinja2/jinja2.gni vendored Normal file
View File

@ -0,0 +1,29 @@
jinja2_sources = [
"//third_party/jinja2/__init__.py",
"//third_party/jinja2/_compat.py",
"//third_party/jinja2/_identifier.py",
"//third_party/jinja2/asyncfilters.py",
"//third_party/jinja2/asyncsupport.py",
"//third_party/jinja2/bccache.py",
"//third_party/jinja2/compiler.py",
"//third_party/jinja2/constants.py",
"//third_party/jinja2/debug.py",
"//third_party/jinja2/defaults.py",
"//third_party/jinja2/environment.py",
"//third_party/jinja2/exceptions.py",
"//third_party/jinja2/ext.py",
"//third_party/jinja2/filters.py",
"//third_party/jinja2/idtracking.py",
"//third_party/jinja2/lexer.py",
"//third_party/jinja2/loaders.py",
"//third_party/jinja2/meta.py",
"//third_party/jinja2/nativetypes.py",
"//third_party/jinja2/nodes.py",
"//third_party/jinja2/optimizer.py",
"//third_party/jinja2/parser.py",
"//third_party/jinja2/runtime.py",
"//third_party/jinja2/sandbox.py",
"//third_party/jinja2/tests.py",
"//third_party/jinja2/utils.py",
"//third_party/jinja2/visitor.py",
]

View File

@ -1,2 +0,0 @@
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Chromium

View File

@ -1,33 +0,0 @@
.cipd
.DS_Store
.gclient
.gclient_entries
.vs
.vscode/*
!.vscode/tasks.json
.idea
coverage.summary
default.profraw
lcov.info
/buildtools
/cmake-build-*/
/out
/testing
/third_party/clang-format
/third_party/catapult
/third_party/cpplint
/third_party/benchmark
/third_party/binutils
/third_party/glslang
/third_party/googletest
/third_party/gpuweb-cts
/third_party/llvm-build
/third_party/protobuf
/third_party/spirv-headers
/third_party/spirv-tools
/tools/clang
/tools/bin
/build*/
/test.wgsl

View File

@ -1,146 +0,0 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
// Available variables which can be used inside of strings.
// ${workspaceRoot}: the root folder of the team
// ${file}: the current opened file
// ${fileBasename}: the current opened file's basename
// ${fileDirname}: the current opened file's dirname
// ${fileExtname}: the current opened file's extension
// ${cwd}: the current working directory of the spawned process
"version": "2.0.0",
"tasks": [
{
"label": "make",
"group": {
"kind": "build",
"isDefault": true
},
"type": "shell",
"osx": {
"command": "sh",
"args": [
"-c",
"cmake --build . && echo Done"
],
"options": {
"cwd": "${workspaceRoot}/build",
},
},
"linux": {
"command": "sh",
"args": [
"-c",
"cmake --build . && echo Done"
],
"options": {
"cwd": "${workspaceRoot}/build",
},
},
"windows": {
// Invokes ninja in the 'out/active' directory, which is created
// with the 'generate' task (see below).
"command": "/C",
"args": [
"ninja && echo Done"
],
"options": {
"cwd": "${workspaceRoot}/out/active",
"shell": {
"executable": "cmd"
}
},
},
"presentation": {
"echo": false,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": false,
"clear": true,
},
"problemMatcher": {
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"label": "configure",
"type": "shell",
"osx": {
"command": "cmake",
"args": [
"..",
"-GNinja",
"-DCMAKE_BUILD_TYPE=${input:buildType}",
],
"options": {
"cwd": "${workspaceRoot}/build"
},
},
"linux": {
"command": "cmake",
"args": [
"..",
"-GNinja",
"-DCMAKE_BUILD_TYPE=${input:buildType}",
],
"options": {
"cwd": "${workspaceRoot}/build"
},
},
"windows": {
// Generates a GN build directory at 'out/<build-type>' with the
// is_debug argument set to true iff the build-type is Debug.
// A symbolic link to this build directory is created at 'out/active'
// which is used to track the active build directory.
"command": "/C",
"args": [
"(IF \"${input:buildType}\" == \"Debug\" ( gn gen \"out\\${input:buildType}\" --args=is_debug=true ) ELSE ( gn gen \"out\\${input:buildType}\" --args=is_debug=false )) && (IF EXIST \"out\\active\" rmdir \"out\\active\" /q /s) && (mklink /j \"out\\active\" \"out\\${input:buildType}\")",
],
"options": {
"shell": {
"executable": "cmd"
}
},
},
"problemMatcher": [],
},
{
"label": "Push branch for review",
"type": "shell",
"command": "git",
"args": [
"push",
"origin",
"HEAD:refs/for/main"
],
"options": {
"cwd": "${workspaceRoot}"
},
"problemMatcher": [],
}
],
"inputs": [
{
"id": "buildType",
"type": "pickString",
"options": [
"Debug",
"Release",
"MinSizeRel",
"RelWithDebInfo",
],
"default": "Debug",
"description": "The type of build",
},
]
}

View File

@ -1,8 +0,0 @@
# This is the list of the Tint authors for copyright purposes.
#
# This does not necessarily list everyone who has contributed code, since in
# some cases, their employer may be the copyright holder. To see the full list
# of contributors, see the revision history in source control.
Google LLC
Vasyl Teliman

View File

@ -1,428 +0,0 @@
# Copyright 2020 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.
cmake_minimum_required(VERSION 3.10.2)
project(tint)
enable_testing()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_DEBUG_POSTFIX "")
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
message(STATUS "No build type selected, default to Debug")
set(CMAKE_BUILD_TYPE "Debug")
endif()
# TINT_IS_SUBPROJECT is 1 if added via add_subdirectory() from another project.
get_directory_property(TINT_IS_SUBPROJECT PARENT_DIRECTORY)
if(TINT_IS_SUBPROJECT)
set(TINT_IS_SUBPROJECT 1)
# If tint is used as a subproject, default to disabling the building of
# documentation and tests. These are unlikely to be desirable, but can be
# enabled.
set(TINT_BUILD_DOCS_DEFAULT OFF)
set(TINT_BUILD_TESTS_DEFAULT OFF)
else()
set(TINT_BUILD_DOCS_DEFAULT ON)
set(TINT_BUILD_TESTS_DEFAULT ON)
endif()
# option_if_not_defined(name description default)
# Behaves like:
# option(name description default)
# If a variable is not already defined with the given name, otherwise the
# function does nothing.
# Simplifies customization by projects that use Dawn as a dependency.
function (option_if_not_defined name description default)
if(NOT DEFINED ${name})
option(${name} ${description} ${default})
endif()
endfunction()
# set_if_not_defined(name value description)
# Behaves like:
# set(${name} ${value} CACHE STRING ${description})
# If a variable is not already defined with the given name, otherwise the
# function does nothing.
# Simplifies customization by projects that use Dawn as a dependency.
function (set_if_not_defined name value description)
if(NOT DEFINED ${name})
set(${name} ${value} CACHE STRING ${description})
endif()
endfunction()
set_if_not_defined(TINT_THIRD_PARTY_DIR "${tint_SOURCE_DIR}/third_party" "Directory in which to find third-party dependencies.")
option_if_not_defined(TINT_BUILD_SAMPLES "Build samples" ON)
option_if_not_defined(TINT_BUILD_DOCS "Build documentation" ${TINT_BUILD_DOCS_DEFAULT})
option_if_not_defined(TINT_DOCS_WARN_AS_ERROR "When building documentation, treat warnings as errors" OFF)
option_if_not_defined(TINT_BUILD_SPV_READER "Build the SPIR-V input reader" ON)
option_if_not_defined(TINT_BUILD_WGSL_READER "Build the WGSL input reader" ON)
option_if_not_defined(TINT_BUILD_GLSL_WRITER "Build the GLSL output writer" ON)
option_if_not_defined(TINT_BUILD_HLSL_WRITER "Build the HLSL output writer" ON)
option_if_not_defined(TINT_BUILD_MSL_WRITER "Build the MSL output writer" ON)
option_if_not_defined(TINT_BUILD_SPV_WRITER "Build the SPIR-V output writer" ON)
option_if_not_defined(TINT_BUILD_WGSL_WRITER "Build the WGSL output writer" ON)
option_if_not_defined(TINT_BUILD_FUZZERS "Build fuzzers" OFF)
option_if_not_defined(TINT_BUILD_SPIRV_TOOLS_FUZZER "Build SPIRV-Tools fuzzer" OFF)
option_if_not_defined(TINT_BUILD_AST_FUZZER "Build AST fuzzer" OFF)
option_if_not_defined(TINT_BUILD_REGEX_FUZZER "Build regex fuzzer" OFF)
option_if_not_defined(TINT_BUILD_BENCHMARKS "Build benchmarks" OFF)
option_if_not_defined(TINT_BUILD_TESTS "Build tests" ${TINT_BUILD_TESTS_DEFAULT})
option_if_not_defined(TINT_BUILD_AS_OTHER_OS "Override OS detection to force building of *_other.cc files" OFF)
option_if_not_defined(TINT_BUILD_REMOTE_COMPILE "Build the remote-compile tool for validating shaders on a remote machine" OFF)
set(TINT_LIB_FUZZING_ENGINE_LINK_OPTIONS "" CACHE STRING "Used by OSS-Fuzz to control, via link options, which fuzzing engine should be used")
option_if_not_defined(TINT_ENABLE_MSAN "Enable memory sanitizer" OFF)
option_if_not_defined(TINT_ENABLE_ASAN "Enable address sanitizer" OFF)
option_if_not_defined(TINT_ENABLE_UBSAN "Enable undefined behaviour sanitizer" OFF)
option_if_not_defined(TINT_EMIT_COVERAGE "Emit code coverage information" OFF)
option_if_not_defined(TINT_CHECK_CHROMIUM_STYLE "Check for [chromium-style] issues during build" OFF)
option_if_not_defined(TINT_SYMBOL_STORE_DEBUG_NAME "Enable storing of name in tint::ast::Symbol to help debugging the AST" OFF)
message(STATUS "Tint build samples: ${TINT_BUILD_SAMPLES}")
message(STATUS "Tint build docs: ${TINT_BUILD_DOCS}")
message(STATUS "Tint build docs with warn as error: ${TINT_DOCS_WARN_AS_ERROR}")
message(STATUS "Tint build SPIR-V reader: ${TINT_BUILD_SPV_READER}")
message(STATUS "Tint build WGSL reader: ${TINT_BUILD_WGSL_READER}")
message(STATUS "Tint build GLSL writer: ${TINT_BUILD_GLSL_WRITER}")
message(STATUS "Tint build HLSL writer: ${TINT_BUILD_HLSL_WRITER}")
message(STATUS "Tint build MSL writer: ${TINT_BUILD_MSL_WRITER}")
message(STATUS "Tint build SPIR-V writer: ${TINT_BUILD_SPV_WRITER}")
message(STATUS "Tint build WGSL writer: ${TINT_BUILD_WGSL_WRITER}")
message(STATUS "Tint build fuzzers: ${TINT_BUILD_FUZZERS}")
message(STATUS "Tint build SPIRV-Tools fuzzer: ${TINT_BUILD_SPIRV_TOOLS_FUZZER}")
message(STATUS "Tint build AST fuzzer: ${TINT_BUILD_AST_FUZZER}")
message(STATUS "Tint build regex fuzzer: ${TINT_BUILD_REGEX_FUZZER}")
message(STATUS "Tint build benchmarks: ${TINT_BUILD_BENCHMARKS}")
message(STATUS "Tint build tests: ${TINT_BUILD_TESTS}")
message(STATUS "Tint build with ASAN: ${TINT_ENABLE_ASAN}")
message(STATUS "Tint build with MSAN: ${TINT_ENABLE_MSAN}")
message(STATUS "Tint build with UBSAN: ${TINT_ENABLE_UBSAN}")
message(STATUS "Tint build checking [chromium-style]: ${TINT_CHECK_CHROMIUM_STYLE}")
message(STATUS "Tint build remote-compile tool: ${TINT_BUILD_REMOTE_COMPILE}")
if (NOT ${TINT_LIB_FUZZING_ENGINE_LINK_OPTIONS} STREQUAL "")
message(STATUS "Using provided LIB_FUZZING_ENGINE options: ${TINT_LIB_FUZZING_ENGINE_LINK_OPTIONS}")
endif()
message(STATUS "Using python3")
find_package(PythonInterp 3 REQUIRED)
if (${TINT_BUILD_SPIRV_TOOLS_FUZZER})
message(STATUS "TINT_BUILD_SPIRV_TOOLS_FUZZER is ON - setting
TINT_BUILD_FUZZERS
TINT_BUILD_SPV_READER
TINT_BUILD_SPV_WRITER
TINT_BUILD_WGSL_READER
TINT_BUILD_WGSL_WRITER
TINT_BUILD_GLSL_WRITER
TINT_BUILD_HLSL_WRITER
TINT_BUILD_MSL_WRITER to ON")
set(TINT_BUILD_FUZZERS ON CACHE BOOL "Build tint fuzzers" FORCE)
set(TINT_BUILD_SPV_READER ON CACHE BOOL "Build SPIR-V reader" FORCE)
set(TINT_BUILD_SPV_WRITER ON CACHE BOOL "Build SPIR-V writer" FORCE)
set(TINT_BUILD_WGSL_READER ON CACHE BOOL "Build WGSL reader" FORCE)
set(TINT_BUILD_WGSL_WRITER ON CACHE BOOL "Build WGSL writer" FORCE)
set(TINT_BUILD_GLSL_WRITER ON CACHE BOOL "Build HLSL writer" FORCE)
set(TINT_BUILD_HLSL_WRITER ON CACHE BOOL "Build HLSL writer" FORCE)
set(TINT_BUILD_MSL_WRITER ON CACHE BOOL "Build MSL writer" FORCE)
endif()
if (${TINT_BUILD_AST_FUZZER})
message(STATUS "TINT_BUILD_AST_FUZZER is ON - setting
TINT_BUILD_FUZZERS
TINT_BUILD_WGSL_READER
TINT_BUILD_WGSL_WRITER
TINT_BUILD_SPV_WRITER
TINT_BUILD_MSL_WRITER
TINT_BUILD_GLSL_WRITER
TINT_BUILD_HLSL_WRITER to ON")
set(TINT_BUILD_FUZZERS ON CACHE BOOL "Build tint fuzzers" FORCE)
set(TINT_BUILD_WGSL_READER ON CACHE BOOL "Build WGSL reader" FORCE)
set(TINT_BUILD_WGSL_WRITER ON CACHE BOOL "Build WGSL writer" FORCE)
set(TINT_BUILD_SPV_WRITER ON CACHE BOOL "Build SPIR-V writer" FORCE)
set(TINT_BUILD_MSL_WRITER ON CACHE BOOL "Build MSL writer" FORCE)
set(TINT_BUILD_GLSL_WRITER ON CACHE BOOL "Build GLSL writer" FORCE)
set(TINT_BUILD_HLSL_WRITER ON CACHE BOOL "Build HLSL writer" FORCE)
endif()
if (${TINT_BUILD_REGEX_FUZZER})
message(STATUS "TINT_BUILD_REGEX_FUZZER is ON - setting
TINT_BUILD_FUZZERS
TINT_BUILD_WGSL_READER
TINT_BUILD_WGSL_WRITER
TINT_BUILD_SPV_WRITER
TINT_BUILD_MSL_WRITER
TINT_BUILD_GLSL_WRITER
TINT_BUILD_HLSL_WRITER to ON")
set(TINT_BUILD_FUZZERS ON CACHE BOOL "Build tint fuzzers" FORCE)
set(TINT_BUILD_WGSL_READER ON CACHE BOOL "Build WGSL reader" FORCE)
set(TINT_BUILD_WGSL_WRITER ON CACHE BOOL "Build WGSL writer" FORCE)
set(TINT_BUILD_SPV_WRITER ON CACHE BOOL "Build SPIR-V writer" FORCE)
set(TINT_BUILD_MSL_WRITER ON CACHE BOOL "Build MSL writer" FORCE)
set(TINT_BUILD_GLSL_WRITER ON CACHE BOOL "Build GLSL writer" FORCE)
set(TINT_BUILD_HLSL_WRITER ON CACHE BOOL "Build HLSL writer" FORCE)
endif()
set(TINT_ROOT_SOURCE_DIR ${PROJECT_SOURCE_DIR})
# CMake < 3.15 sets /W3 in CMAKE_CXX_FLAGS. Remove it if it's there.
# See https://gitlab.kitware.com/cmake/cmake/-/issues/18317
if (MSVC)
if (CMAKE_CXX_FLAGS MATCHES "/W3")
string(REPLACE "/W3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
endif()
if (${TINT_CHECK_CHROMIUM_STYLE})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xclang -add-plugin -Xclang find-bad-constructs")
endif()
if (${TINT_BUILD_SPV_READER})
include_directories("${TINT_ROOT_SOURCE_DIR}/third_party/spirv-tools/include")
endif()
if((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND (CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))
set(COMPILER_IS_CLANG_CL TRUE)
endif()
if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") OR
((CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND
(NOT COMPILER_IS_CLANG_CL)))
set(COMPILER_IS_LIKE_GNU TRUE)
endif()
# Enable msbuild multiprocessor builds
if (MSVC AND NOT COMPILER_IS_CLANG_CL)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
endif()
set(TINT_OS_CC_SUFFIX "other")
if (NOT TINT_BUILD_AS_OTHER_OS)
if(UNIX OR APPLE)
set(TINT_OS_CC_SUFFIX "posix")
set(TINT_OS_CC_SUFFIX "posix")
elseif(WIN32)
set(TINT_OS_CC_SUFFIX "windows")
set(TINT_OS_CC_SUFFIX "windows")
endif()
endif()
if(${TINT_BUILD_DOCS})
find_package(Doxygen)
if(DOXYGEN_FOUND)
set(DOXYGEN_WARN_AS_ERROR NO)
if(TINT_DOCS_WARN_AS_ERROR)
set(DOXYGEN_WARN_AS_ERROR YES)
endif()
set(DOXYGEN_WARN_FORMAT "$file:$line: $text")
if (MSVC)
set(DOXYGEN_WARN_FORMAT "$file($line): $text")
endif()
add_custom_target(tint-docs ALL
COMMAND ${CMAKE_COMMAND}
-E env
"DOXYGEN_OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}/docs"
"DOXYGEN_WARN_AS_ERROR=${DOXYGEN_WARN_AS_ERROR}"
"DOXYGEN_WARN_FORMAT=${DOXYGEN_WARN_FORMAT}"
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating API documentation"
VERBATIM)
else()
message("Doxygen not found. Skipping documentation")
endif(DOXYGEN_FOUND)
endif()
function(tint_core_compile_options TARGET)
target_include_directories(${TARGET} PUBLIC "${TINT_ROOT_SOURCE_DIR}")
target_include_directories(${TARGET} PUBLIC "${TINT_ROOT_SOURCE_DIR}/include")
if (${TINT_BUILD_SPV_READER} OR ${TINT_BUILD_SPV_WRITER})
target_include_directories(${TARGET} PUBLIC
"${TINT_ROOT_SOURCE_DIR}/third_party/spirv-headers/include")
endif()
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_SPV_READER=$<BOOL:${TINT_BUILD_SPV_READER}>)
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_WGSL_READER=$<BOOL:${TINT_BUILD_WGSL_READER}>)
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_GLSL_WRITER=$<BOOL:${TINT_BUILD_GLSL_WRITER}>)
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_HLSL_WRITER=$<BOOL:${TINT_BUILD_HLSL_WRITER}>)
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_MSL_WRITER=$<BOOL:${TINT_BUILD_MSL_WRITER}>)
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_SPV_WRITER=$<BOOL:${TINT_BUILD_SPV_WRITER}>)
target_compile_definitions(${TARGET} PUBLIC -DTINT_BUILD_WGSL_WRITER=$<BOOL:${TINT_BUILD_WGSL_WRITER}>)
if (COMPILER_IS_LIKE_GNU)
target_compile_options(${TARGET} PRIVATE
-std=c++17
-fno-exceptions
-fno-rtti
)
if (${TINT_ENABLE_MSAN})
target_compile_options(${TARGET} PRIVATE -fsanitize=memory)
target_link_options(${TARGET} PRIVATE -fsanitize=memory)
elseif (${TINT_ENABLE_ASAN})
target_compile_options(${TARGET} PRIVATE -fsanitize=address)
target_link_options(${TARGET} PRIVATE -fsanitize=address)
elseif (${TINT_ENABLE_UBSAN})
target_compile_options(${TARGET} PRIVATE -fsanitize=undefined)
target_link_options(${TARGET} PRIVATE -fsanitize=undefined)
endif()
endif(COMPILER_IS_LIKE_GNU)
if (TINT_EMIT_COVERAGE)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
target_compile_options(${TARGET} PRIVATE "--coverage")
target_link_options(${TARGET} PRIVATE "gcov")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(${TARGET} PRIVATE "-fprofile-instr-generate" "-fcoverage-mapping")
target_link_options(${TARGET} PRIVATE "-fprofile-instr-generate" "-fcoverage-mapping")
else()
message(FATAL_ERROR "Coverage generation not supported for the ${CMAKE_CXX_COMPILER_ID} toolchain")
endif()
endif(TINT_EMIT_COVERAGE)
endfunction()
function(tint_default_compile_options TARGET)
tint_core_compile_options(${TARGET})
set(COMMON_GNU_OPTIONS
-Wall
-Werror
-Wextra
-Wno-documentation-unknown-command
-Wno-padded
-Wno-switch-enum
-Wno-unknown-pragmas
)
set(COMMON_CLANG_OPTIONS
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-format-pedantic
-Wno-return-std-move-in-c++11
-Wno-unknown-warning-option
-Wno-undefined-var-template
-Wno-used-but-marked-unused
-Weverything
)
if (COMPILER_IS_LIKE_GNU)
target_compile_options(${TARGET} PRIVATE
-pedantic-errors
${COMMON_GNU_OPTIONS}
)
if (("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") OR
("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang"))
target_compile_options(${TARGET} PRIVATE
${COMMON_CLANG_OPTIONS}
)
endif()
endif(COMPILER_IS_LIKE_GNU)
if (MSVC)
# Specify /EHs for exception handling.
target_compile_options(${TARGET} PRIVATE
/bigobj
/EHsc
/W4
/WX
/wd4068
/wd4127
/wd4244
/wd4267
/wd4324
/wd4458
/wd4514
/wd4571
/wd4625
/wd4626
/wd4710
/wd4774
/wd4820
/wd5026
/wd5027
)
# When building with clang-cl on Windows, try to match our clang build
# options as much as possible.
if (COMPILER_IS_CLANG_CL)
target_compile_options(${TARGET} PRIVATE
${COMMON_GNU_OPTIONS}
${COMMON_CLANG_OPTIONS}
# Disable warnings that are usually disabled in downstream deps for
# gcc/clang, but aren't for clang-cl.
-Wno-global-constructors
-Wno-zero-as-null-pointer-constant
-Wno-shorten-64-to-32
-Wno-shadow-field-in-constructor
-Wno-reserved-id-macro
-Wno-language-extension-token
)
endif()
endif()
endfunction()
add_subdirectory(third_party)
add_subdirectory(src)
if (TINT_BUILD_SAMPLES)
add_subdirectory(samples)
endif()
if (TINT_BUILD_FUZZERS)
add_subdirectory(fuzzers)
endif()
add_custom_target(tint-lint
COMMAND ./tools/lint
WORKING_DIRECTORY ${TINT_ROOT_SOURCE_DIR}
COMMENT "Running linter"
VERBATIM)
add_custom_target(tint-format
COMMAND ./tools/format
WORKING_DIRECTORY ${TINT_ROOT_SOURCE_DIR}
COMMENT "Running formatter"
VERBATIM)
if (TINT_EMIT_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# Generates a lcov.info file at the project root.
# This can be used by tools such as VSCode's Coverage Gutters extension to
# visualize code coverage in the editor.
get_filename_component(CLANG_BIN_DIR ${CMAKE_C_COMPILER} DIRECTORY)
set(PATH_WITH_CLANG "${CLANG_BIN_DIR}:$ENV{PATH}")
add_custom_target(tint-generate-coverage
COMMAND ${CMAKE_COMMAND} -E env PATH=${PATH_WITH_CLANG} ./tools/tint-generate-coverage $<TARGET_FILE:tint_unittests>
DEPENDS tint_unittests
WORKING_DIRECTORY ${TINT_ROOT_SOURCE_DIR}
COMMENT "Generating tint coverage data"
VERBATIM)
endif()
if (TINT_BUILD_REMOTE_COMPILE)
add_subdirectory(tools/src/cmd/remote-compile)
endif()

View File

@ -1,100 +0,0 @@
{
"configurations": [
{
"name": "x64-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"inheritEnvironments": [ "msvc_x64_x64" ],
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"variables": []
},
{
"name": "x64-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ],
"variables": []
},
{
"name": "x86-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x86" ],
"variables": []
},
{
"name": "x86-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x86" ],
"variables": []
},
{
"name": "x64-Clang-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "clang_cl_x64_x64" ],
"variables": []
},
{
"name": "x64-Clang-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "clang_cl_x64_x64" ],
"variables": []
},
{
"name": "x86-Clang-Debug",
"generator": "Ninja",
"configurationType": "Debug",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "clang_cl_x86" ],
"variables": []
},
{
"name": "x86-Clang-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "clang_cl_x86" ],
"variables": []
}
]
}

View File

@ -1,93 +0,0 @@
# Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of
experience, education, socio-economic status, nationality, personal appearance,
race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
This Code of Conduct also applies outside the project spaces when the Project
Steward has a reasonable belief that an individual's behavior may have a
negative impact on the project or its community.
## Conflict Resolution
We do not believe that all conflict is bad; healthy debate and disagreement
often yield positive results. However, it is never okay to be disrespectful or
to engage in behavior that violates the projects code of conduct.
If you see someone violating the code of conduct, you are encouraged to address
the behavior directly with those involved. Many issues can be resolved quickly
and easily, and this gives people more control over the outcome of their
dispute. If you are unable to resolve the matter for any reason, or if the
behavior is threatening or harassing, report it. We are dedicated to providing
an environment where participants feel welcome and safe.
Reports should be directed to David Neto <dneto@google.com>, the
Project Steward(s) for Tint. It is the Project Stewards duty to
receive and address reported violations of the code of conduct. They will then
work with a committee consisting of representatives from the Open Source
Programs Office and the Google Open Source Strategy team. If for any reason you
are uncomfortable reaching out the Project Steward, please email
opensource@google.com.
We will investigate every complaint, but you may not receive a direct response.
We will use our discretion in determining when and how to follow up on reported
incidents, which may range from not taking action to permanent expulsion from
the project and project-sponsored spaces. We will notify the accused of the
report and provide them an opportunity to discuss it before any action is taken.
The identity of the reporter will be omitted from the details of the report
supplied to the accused. In potentially harmful situations, such as ongoing
harassment or threats to anyone's safety, we may take action without notice.
## Attribution
This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
available at
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

View File

@ -1,45 +0,0 @@
# How to Contribute
We'd love to accept your patches and contributions to this project. There are
just a few small guidelines you need to follow.
## Contributor License Agreement
Contributions to this project must be accompanied by a Contributor License
Agreement. You (or your employer) retain the copyright to your contribution;
this simply gives us permission to use and redistribute your contributions as
part of the project. Head over to <https://cla.developers.google.com/> to see
your current agreements on file or to sign a new one.
You generally only need to submit a CLA once, so if you've already submitted one
(even if it was for a different project), you probably don't need to do it
again.
## Code reviews
All submissions, including submissions by project members, require review. We
use [Dawn's Gerrit](https://dawn-review.googlesource.com/) for this purpose.
Submissions should follow the [Tint style guide](docs/style_guide.md).
## Pushing to Gerrit
Each change requires a `Change-Id` field in the commit message, which is generated by the [Gerrit commit-msg hook](](https://gerrit-review.googlesource.com/Documentation/cmd-hook-commit-msg.html)). \
In a bash terminal, with the current path set to your tint source tree, this can be obtained by running the following:
```bash
f=`git rev-parse --git-dir`/hooks/commit-msg ; mkdir -p $(dirname $f) ; curl -Lo $f https://gerrit-review.googlesource.com/tools/hooks/commit-msg ; chmod +x $f
```
If you've already locally committed a change without the `Change-Id`, running `git commit --amend` will add the missing `Change-Id`.
To create a Gerrit change for review, type:
```bash
git push origin HEAD:refs/for/main
```
## Community Guidelines
This project follows
[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/).

View File

@ -1 +0,0 @@
set noparent

213
third_party/tint/DEPS vendored
View File

@ -1,213 +0,0 @@
use_relative_paths = True
gclient_gn_args_file = 'build/config/gclient_args.gni'
gclient_gn_args = [
'generate_location_tags',
]
vars = {
'chromium_git': 'https://chromium.googlesource.com',
'github': '/external/github.com',
'benchmark_revision': 'e991355c02b93fe17713efe04cbc2e278e00fdbd',
'build_revision': '555c8b467c21e2c4b22d00e87e3faa0431df9ac2',
'buildtools_revision': 'f78b4b9f33bd8ef9944d5ce643daff1c31880189',
'catapult_revision': 'fa35beefb3429605035f98211ddb8750dee6a13d',
'clang_format_revision': '2271e89c145a5e27d6c110b6a1113c057a8301a3',
'clang_revision': '8b7330592cb85ba09505a6be7bacabd0ad6160a3',
'glslang_revision': '4b7b86d568b40f4b076259dc2fc4cdd006340f34',
'googletest_revision': '6b74da4757a549563d7c37c8fae3e704662a043b',
'gpuweb_cts_revision': 'b0291fd966b55a5efc496772555b94842bde1085',
'libcxx_revision': '79a2e924d96e2fc1e4b937c42efd08898fa472d7',
'libcxxabi_revision': '2715a6c0de8dac4c7674934a6b3d30ba0c685271',
'protobuf_revision': 'fde7cf7358ec7cd69e8db9be4f1fa6a5c431386a',
'spirv_headers_revision': 'eddd4dfc930f1374a70797460240a501c7d333f7',
'spirv_tools_revision': 'df2aad68b98279412494a6d449bd71b6756e699b',
'testing_revision': 'd485ae97b7900c1fb7edfbe2901ae5adcb120865',
'tint_gn_revision': 'git_revision:281ba2c91861b10fec7407c4b6172ec3d4661243',
# We don't use location metadata in our test isolates.
'generate_location_tags': False,
}
deps = {
'third_party/gpuweb-cts': Var('chromium_git') + Var('github') +
'/gpuweb/cts.git@' + Var('gpuweb_cts_revision'),
'third_party/spirv-headers': Var('chromium_git') + Var('github') +
'/KhronosGroup/SPIRV-Headers.git@' + Var('spirv_headers_revision'),
'third_party/spirv-tools': Var('chromium_git') + Var('github') +
'/KhronosGroup//SPIRV-Tools.git@' + Var('spirv_tools_revision'),
'third_party/glslang': Var('chromium_git') + Var('github') +
'/KhronosGroup/glslang.git@' + Var('glslang_revision'),
# Dependencies required to use GN/Clang in standalone
'build': Var('chromium_git') + '/chromium/src/build@' +
Var('build_revision'),
'buildtools': Var('chromium_git') + '/chromium/src/buildtools@' +
Var('buildtools_revision'),
'tools/clang': Var('chromium_git') + '/chromium/src/tools/clang@' +
Var('clang_revision'),
'buildtools/clang_format/script': {
'url': Var('chromium_git') +
'/external/github.com/llvm/llvm-project/clang/tools/clang-format.git@' +
Var('clang_format_revision'),
},
'buildtools/linux64': {
'packages': [{
'package': 'gn/gn/linux-amd64',
'version': Var('tint_gn_revision'),
}],
'dep_type': 'cipd',
'condition': 'host_os == "linux"',
},
'buildtools/mac': {
'packages': [{
'package': 'gn/gn/mac-${{arch}}',
'version': Var('tint_gn_revision'),
}],
'dep_type': 'cipd',
'condition': 'host_os == "mac"',
},
'buildtools/win': {
'packages': [{
'package': 'gn/gn/windows-amd64',
'version': Var('tint_gn_revision'),
}],
'dep_type': 'cipd',
'condition': 'host_os == "win"',
},
'buildtools/third_party/libc++/trunk':
Var('chromium_git') +
'/external/github.com/llvm/llvm-project/libcxx.git@' +
Var('libcxx_revision'),
'buildtools/third_party/libc++abi/trunk':
Var('chromium_git') +
'/external/github.com/llvm/llvm-project/libcxxabi.git@' +
Var('libcxxabi_revision'),
# Dependencies required for testing
'testing': Var('chromium_git') + '/chromium/src/testing@' +
Var('testing_revision'),
'third_party/catapult': Var('chromium_git') + '/catapult.git@' +
Var('catapult_revision'),
'third_party/benchmark': Var('chromium_git') + Var('github') +
'/google/benchmark.git@' + Var('benchmark_revision'),
'third_party/googletest': Var('chromium_git') + Var('github') +
'/google/googletest.git@' + Var('googletest_revision'),
'third_party/protobuf': Var('chromium_git') + Var('github') +
'/protocolbuffers/protobuf.git@' + Var('protobuf_revision'),
}
hooks = [
# Pull clang-format binaries using checked-in hashes.
{
'name': 'clang_format_win',
'pattern': '.',
'condition': 'host_os == "win"',
'action': [ 'download_from_google_storage',
'--no_resume',
'--platform=win32',
'--no_auth',
'--bucket', 'chromium-clang-format',
'-s', 'buildtools/win/clang-format.exe.sha1',
],
},
{
'name': 'clang_format_mac',
'pattern': '.',
'condition': 'host_os == "mac"',
'action': [ 'download_from_google_storage',
'--no_resume',
'--platform=darwin',
'--no_auth',
'--bucket', 'chromium-clang-format',
'-s', 'buildtools/mac/clang-format.sha1',
],
},
{
'name': 'clang_format_linux',
'pattern': '.',
'condition': 'host_os == "linux"',
'action': [ 'download_from_google_storage',
'--no_resume',
'--platform=linux*',
'--no_auth',
'--bucket', 'chromium-clang-format',
'-s', 'buildtools/linux64/clang-format.sha1',
],
},
# Pull the compilers and system libraries for hermetic builds
{
'name': 'sysroot_x86',
'pattern': '.',
'condition': 'checkout_linux and ((checkout_x86 or checkout_x64))',
'action': ['python3', 'build/linux/sysroot_scripts/install-sysroot.py',
'--arch=x86'],
},
{
'name': 'sysroot_x64',
'pattern': '.',
'condition': 'checkout_linux and (checkout_x64)',
'action': ['python3', 'build/linux/sysroot_scripts/install-sysroot.py',
'--arch=x64'],
},
{
# Update the Mac toolchain if necessary.
'name': 'mac_toolchain',
'pattern': '.',
'condition': 'checkout_mac',
'action': ['python3', 'build/mac_toolchain.py'],
},
{
# Update the Windows toolchain if necessary. Must run before 'clang' below.
'name': 'win_toolchain',
'pattern': '.',
'condition': 'checkout_win',
'action': ['python3', 'build/vs_toolchain.py', 'update', '--force'],
},
{
# Note: On Win, this should run after win_toolchain, as it may use it.
'name': 'clang',
'pattern': '.',
'action': ['python3', 'tools/clang/scripts/update.py'],
},
{
# Pull rc binaries using checked-in hashes.
'name': 'rc_win',
'pattern': '.',
'condition': 'checkout_win and (host_os == "win")',
'action': [ 'download_from_google_storage',
'--no_resume',
'--no_auth',
'--bucket', 'chromium-browser-clang/rc',
'-s', 'build/toolchain/win/rc/win/rc.exe.sha1',
],
},
# Update build/util/LASTCHANGE.
{
'name': 'lastchange',
'pattern': '.',
'action': ['python3', 'build/util/lastchange.py',
'-o', 'build/util/LASTCHANGE'],
},
]
recursedeps = [
# buildtools provides clang_format, libc++, and libc++abi
'buildtools',
]

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +0,0 @@
amaiorano@google.com
bclayton@chromium.org
bclayton@google.com
cwallez@chromium.org
dneto@google.com
jrprice@google.com
rharrison@chromium.org
rharrison@google.com
sarahmashay@google.com

View File

@ -1,158 +0,0 @@
# Copyright 2020 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.
"""Presubmit script for Tint.
See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into depot_tools.
"""
import re
USE_PYTHON3 = True
def _LicenseHeader(input_api):
"""Returns the license header regexp."""
# Accept any year number from 2019 to the current year
current_year = int(input_api.time.strftime('%Y'))
allowed_years = (str(s) for s in reversed(xrange(2019, current_year + 1)))
years_re = '(' + '|'.join(allowed_years) + ')'
license_header = (
r'.*? Copyright( \(c\))? %(year)s The Tint [Aa]uthors\n '
r'.*?\n'
r'.*? Licensed under the Apache License, Version 2.0 (the "License");\n'
r'.*? you may not use this file except in compliance with the License.\n'
r'.*? You may obtain a copy of the License at\n'
r'.*?\n'
r'.*? http://www.apache.org/licenses/LICENSE-2.0\n'
r'.*?\n'
r'.*? Unless required by applicable law or agreed to in writing, software\n'
r'.*? distributed under the License is distributed on an "AS IS" BASIS,\n'
r'.*? WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n'
r'.*? See the License for the specific language governing permissions and\n'
r'.*? limitations under the License.\n') % {
'year': years_re,
}
return license_header
REGEXES = [
r"(?i)black[-_]?list",
r"(?i)white[-_]?list",
r"(?i)gr[ea]y[-_]?list",
r"(?i)(first class citizen)",
r"(?i)black[-_]?hat",
r"(?i)white[-_]?hat",
r"(?i)gr[ea]y[-_]?hat",
r"(?i)master",
r"(?i)slave",
r"(?i)\bhim\b",
r"(?i)\bhis\b",
r"(?i)\bshe\b",
r"(?i)\bher\b",
r"(?i)\bguys\b",
r"(?i)\bhers\b",
r"(?i)\bman\b",
r"(?i)\bwoman\b",
r"(?i)\she\s",
r"(?i)\she$",
r"(?i)^he\s",
r"(?i)^he$",
r"(?i)\she['|\u2019]d\s",
r"(?i)\she['|\u2019]d$",
r"(?i)^he['|\u2019]d\s",
r"(?i)^he['|\u2019]d$",
r"(?i)\she['|\u2019]s\s",
r"(?i)\she['|\u2019]s$",
r"(?i)^he['|\u2019]s\s",
r"(?i)^he['|\u2019]s$",
r"(?i)\she['|\u2019]ll\s",
r"(?i)\she['|\u2019]ll$",
r"(?i)^he['|\u2019]ll\s",
r"(?i)^he['|\u2019]ll$",
r"(?i)grandfather",
r"(?i)\bmitm\b",
r"(?i)\bcrazy\b",
r"(?i)\binsane\b",
r"(?i)\bblind\sto\b",
r"(?i)\bflying\sblind\b",
r"(?i)\bblind\seye\b",
r"(?i)\bcripple\b",
r"(?i)\bcrippled\b",
r"(?i)\bdumb\b",
r"(?i)\bdummy\b",
r"(?i)\bparanoid\b",
r"(?i)\bsane\b",
r"(?i)\bsanity\b",
r"(?i)red[-_]?line",
]
REGEX_LIST = []
for reg in REGEXES:
REGEX_LIST.append(re.compile(reg))
def CheckNonInclusiveLanguage(input_api, output_api, source_file_filter=None):
"""Checks the files for non-inclusive language."""
matches = []
for f in input_api.AffectedFiles(include_deletes=False,
file_filter=source_file_filter):
for line_num, line in f.ChangedContents():
for reg in REGEX_LIST:
match = reg.search(line)
if match:
matches.append(
"{} ({}): found non-inclusive language: {}".format(
f.LocalPath(), line_num, match.group(0)))
if len(matches):
return [
output_api.PresubmitPromptWarning('Non-inclusive language found:',
items=matches)
]
return []
def CheckChange(input_api, output_api):
results = []
results += input_api.canned_checks.CheckChangeHasDescription(
input_api, output_api)
results += input_api.canned_checks.CheckPatchFormatted(input_api,
output_api,
check_python=True)
results += input_api.canned_checks.CheckGNFormatted(input_api, output_api)
results += input_api.canned_checks.CheckChangeHasNoCrAndHasOnlyOneEol(
input_api, output_api)
results += input_api.canned_checks.CheckChangeHasNoTabs(
input_api, output_api)
results += input_api.canned_checks.CheckChangeTodoHasOwner(
input_api, output_api)
results += input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
input_api, output_api)
results += input_api.canned_checks.CheckDoNotSubmit(input_api, output_api)
results += input_api.canned_checks.CheckChangeLintsClean(input_api,
output_api,
lint_filters="")
results += CheckNonInclusiveLanguage(input_api, output_api)
return results
def CheckChangeOnUpload(input_api, output_api):
return CheckChange(input_api, output_api)
def CheckChangeOnCommit(input_api, output_api):
return CheckChange(input_api, output_api)

View File

@ -1,106 +0,0 @@
# Tint
Tint is a compiler for the WebGPU Shader Language (WGSL).
This is not an officially supported Google product.
## Requirements
* Git
* CMake (3.10.2 or later)
* Ninja (or other build tool)
* Python, for fetching dependencies
* [depot_tools] in your path
## Build options
* `TINT_BUILD_SPV_READER` : enable the SPIR-V input reader (off by default)
* `TINT_BUILD_WGSL_READER` : enable the WGSL input reader (on by default)
* `TINT_BUILD_SPV_WRITER` : enable the SPIR-V output writer (on by default)
* `TINT_BUILD_WGSL_WRITER` : enable the WGSL output writer (on by default)
* `TINT_BUILD_FUZZERS` : enable building fuzzzers (off by default)
## Building
Tint uses Chromium dependency management so you need to install [depot_tools]
and add it to your PATH.
[depot_tools]: http://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up
### Getting source & dependencies
```sh
# Clone the repo as "tint"
git clone https://dawn.googlesource.com/tint tint
cd tint
# Bootstrap the gclient configuration
cp standalone.gclient .gclient
# Fetch external dependencies and toolchains with gclient
gclient sync
```
### Compiling using CMake + Ninja
```sh
mkdir -p out/Debug
cd out/Debug
cmake -GNinja ../..
ninja # or autoninja
```
### Compiling using CMake + make
```sh
mkdir -p out/Debug
cd out/Debug
cmake ../..
make # -j N for N-way parallel build
```
### Compiling using gn + ninja
```sh
mkdir -p out/Debug
gn gen out/Debug
autoninja -C out/Debug
```
### Fuzzers on MacOS
If you are attempting fuzz, using `TINT_BUILD_FUZZERS=ON`, the version of llvm
in the XCode SDK does not have the needed libfuzzer functionality included.
The build error that you will see from using the XCode SDK will look something
like this:
```
ld: file not found:/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/11.0.0/lib/darwin/libclang_rt.fuzzer_osx.a
```
The solution to this problem is to use a full version llvm, like what you would
get via homebrew, `brew install llvm`, and use something like `CC=<path to full
clang> cmake ..` to setup a build using that toolchain.
### Checking [chromium-style] issues in CMake builds
The gn based work flow uses the Chromium toolchain for building in anticipation
of integration of Tint into Chromium based projects. This toolchain has
additional plugins for checking for style issues, which are marked with
[chromium-style] in log messages. This means that this toolchain is more strict
then the default clang toolchain.
In the future we will have a CQ that will build this work flow and flag issues
automatically. Until that is in place, to avoid causing breakages you can run
the [chromium-style] checks using the CMake based work flows. This requires
setting `CC` to the version of clang checked out by `gclient sync` and setting
the `TINT_CHECK_CHROMIUM_STYLE` to `ON`.
```sh
mkdir -p out/style
cd out/style
cmake ../..
CC=../../third_party/llvm-build/Release+Asserts/bin/clang cmake -DTINT_CHECK_CHROMIUM_STYLE=ON ../../ # add -GNinja for ninja builds
```
## Issues
Please file any issues or feature requests at
https://bugs.chromium.org/p/tint/issues/entry
## Contributing
Please see the CONTRIBUTING and CODE_OF_CONDUCT files on how to contribute to
Tint.
Tint has a process for supporting [experimental extensions](docs/experimental_extensions.md).

View File

@ -1,114 +0,0 @@
# Copyright 2020 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.
function(add_tint_fuzzer NAME)
add_executable(${NAME}
${NAME}.cc
cli.cc
cli.h
data_builder.h
fuzzer_init.cc
fuzzer_init.h
mersenne_twister_engine.cc
mersenne_twister_engine.h
random_generator.cc
random_generator.h
random_generator_engine.cc
random_generator_engine.h
shuffle_transform.cc
shuffle_transform.h
tint_common_fuzzer.cc
tint_common_fuzzer.h
tint_reader_writer_fuzzer.h
transform_builder.h
)
target_link_libraries(${NAME} libtint-fuzz)
tint_default_compile_options(${NAME})
target_compile_options(${NAME} PRIVATE -Wno-missing-prototypes)
endfunction()
if (${TINT_BUILD_WGSL_READER} AND ${TINT_BUILD_WGSL_WRITER})
add_tint_fuzzer(tint_wgsl_reader_wgsl_writer_fuzzer)
endif()
if (${TINT_BUILD_WGSL_READER} AND ${TINT_BUILD_SPV_WRITER})
add_tint_fuzzer(tint_all_transforms_fuzzer)
add_tint_fuzzer(tint_binding_remapper_fuzzer)
add_tint_fuzzer(tint_first_index_offset_fuzzer)
add_tint_fuzzer(tint_renamer_fuzzer)
add_tint_fuzzer(tint_robustness_fuzzer)
add_tint_fuzzer(tint_single_entry_point_fuzzer)
add_tint_fuzzer(tint_vertex_pulling_fuzzer)
add_tint_fuzzer(tint_wgsl_reader_spv_writer_fuzzer)
endif()
if (${TINT_BUILD_WGSL_READER} AND ${TINT_BUILD_HLSL_WRITER})
add_tint_fuzzer(tint_wgsl_reader_hlsl_writer_fuzzer)
endif()
if (${TINT_BUILD_WGSL_READER} AND ${TINT_BUILD_MSL_WRITER})
add_tint_fuzzer(tint_wgsl_reader_msl_writer_fuzzer)
endif()
if (${TINT_BUILD_SPV_READER} AND ${TINT_BUILD_WGSL_WRITER})
add_tint_fuzzer(tint_spv_reader_wgsl_writer_fuzzer)
endif()
if (${TINT_BUILD_SPV_READER} AND ${TINT_BUILD_SPV_WRITER})
add_tint_fuzzer(tint_spv_reader_spv_writer_fuzzer)
endif()
if (${TINT_BUILD_SPV_READER} AND ${TINT_BUILD_HLSL_WRITER})
add_tint_fuzzer(tint_spv_reader_hlsl_writer_fuzzer)
endif()
if (${TINT_BUILD_SPV_READER} AND ${TINT_BUILD_MSL_WRITER})
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_SPIRV_TOOLS_FUZZER})
add_subdirectory(tint_spirv_tools_fuzzer)
endif()
if (${TINT_BUILD_AST_FUZZER})
add_subdirectory(tint_ast_fuzzer)
endif()
if (${TINT_BUILD_REGEX_FUZZER})
add_subdirectory(tint_regex_fuzzer)
endif()
if (${TINT_BUILD_WGSL_READER}
AND ${TINT_BUILD_HLSL_WRITER}
AND ${TINT_BUILD_MSL_WRITER}
AND ${TINT_BUILD_SPV_WRITER}
AND ${TINT_BUILD_WGSL_WRITER})
add_executable(tint_black_box_fuzz_target
mersenne_twister_engine.cc
mersenne_twister_engine.h
random_generator.cc
random_generator.h
random_generator_engine.cc
random_generator_engine.h
tint_black_box_fuzz_target.cc
tint_common_fuzzer.cc
tint_common_fuzzer.h
)
target_link_libraries(tint_black_box_fuzz_target libtint)
tint_default_compile_options(tint_black_box_fuzz_target)
endif()

View File

@ -1,116 +0,0 @@
// 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 "fuzzers/cli.h"
#include <cstring>
#include <iostream>
#include <limits>
#include <sstream>
#include <string>
#include <utility>
namespace tint {
namespace fuzzers {
namespace {
const char* const kHelpMessage = R"(
This is a fuzzer for the Tint compiler that works by mutating the AST.
Below is a list of all supported parameters for this fuzzer. You may want to
run it with -help=1 to check out libfuzzer parameters.
-tint_dump_input=
If `true`, the fuzzer will dump input data to a file with
name tint_input_<hash>.spv/wgsl, where the hash is the hash
of the input data.
-tint_help
Show this message. Note that there is also a -help=1
parameter that will display libfuzzer's help message.
-tint_enforce_validity=
If `true`, the fuzzer will enforce that Tint does not
generate invalid shaders. Currently `false` by default
since options provided by the fuzzer are not guaranteed
to be correct.
See https://bugs.chromium.org/p/tint/issues/detail?id=1356
)";
[[noreturn]] void InvalidParam(const std::string& param) {
std::cout << "Invalid value for " << param << std::endl;
std::cout << kHelpMessage << std::endl;
exit(1);
}
bool ParseBool(const std::string& value, bool* out) {
if (value.compare("true") == 0) {
*out = true;
} else if (value.compare("false") == 0) {
*out = false;
} else {
return false;
}
return true;
}
} // namespace
CliParams ParseCliParams(int* argc, char** argv) {
CliParams cli_params;
auto help = false;
for (int i = *argc - 1; i > 0; --i) {
std::string param(argv[i]);
auto recognized_parameter = true;
if (std::string::npos != param.find("-tint_dump_input=")) {
if (!ParseBool(param.substr(std::string("-tint_dump_input=").length()),
&cli_params.dump_input)) {
InvalidParam(param);
}
} else if (std::string::npos != param.find("-tint_help")) {
help = true;
} else if (std::string::npos != param.find("-tint_enforce_validity=")) {
if (!ParseBool(
param.substr(std::string("-tint_enforce_validity=").length()),
&cli_params.enforce_validity)) {
InvalidParam(param);
}
} else {
recognized_parameter = false;
}
if (recognized_parameter) {
// Remove the recognized parameter from the list of all parameters by
// swapping it with the last one. This will suppress warnings in the
// libFuzzer about unrecognized parameters. By default, libFuzzer thinks
// that all user-defined parameters start with two dashes. However, we are
// forced to use a single one to make the fuzzer compatible with the
// ClusterFuzz.
std::swap(argv[i], argv[*argc - 1]);
*argc -= 1;
}
}
if (help) {
std::cout << kHelpMessage << std::endl;
exit(0);
}
return cli_params;
}
} // namespace fuzzers
} // namespace tint

View File

@ -1,44 +0,0 @@
// 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.
#ifndef FUZZERS_CLI_H_
#define FUZZERS_CLI_H_
#include <cstdint>
namespace tint {
namespace fuzzers {
/// CLI parameters accepted by the fuzzer. Type -tint_help in the CLI to see the
/// help message
struct CliParams {
bool dump_input = false;
bool enforce_validity = false;
};
/// @brief Parses CLI parameters.
///
/// This function will exit the process with non-zero return code if some
/// parameters are invalid. This function will remove recognized parameters from
/// `argv` and adjust `argc` accordingly.
///
/// @param argc - the total number of parameters.
/// @param argv - array of all CLI parameters.
/// @return parsed parameters.
CliParams ParseCliParams(int* argc, char** argv);
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_CLI_H_

View File

@ -1,242 +0,0 @@
// 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.
#ifndef FUZZERS_DATA_BUILDER_H_
#define FUZZERS_DATA_BUILDER_H_
#include <cassert>
#include <functional>
#include <string>
#include <unordered_map>
#include <vector>
#include "fuzzers/random_generator.h"
#include "src/writer/hlsl/generator.h"
#include "src/writer/msl/generator.h"
namespace tint {
namespace fuzzers {
/// Builder for generic pseudo-random data
class DataBuilder {
public:
/// @brief Initializes the internal engine using a seed value
/// @param seed - seed value passed to engine
explicit DataBuilder(uint64_t seed) : generator_(seed) {}
/// @brief Initializes the internal engine using seed data
/// @param data - data fuzzer to calculate seed from
/// @param size - size of data buffer
explicit DataBuilder(const uint8_t* data, size_t size)
: generator_(RandomGenerator::CalculateSeed(data, size)) {
assert(data != nullptr && "|data| must be !nullptr");
}
~DataBuilder() = default;
DataBuilder(DataBuilder&&) = default;
/// Generate pseudo-random data of a specific type
/// @tparam T - type of data to produce
/// @returns pseudo-random data of type T
template <typename T>
T build() {
return BuildImpl<T>::impl(this);
}
/// Generate pseudo-random data of a specific type in a vector
/// @tparam T - data type held vector
/// @returns pseudo-random data of type std::vector<T>
template <typename T>
std::vector<T> vector() {
auto count = build<uint8_t>();
std::vector<T> out(count);
for (uint8_t i = 0; i < count; i++) {
out[i] = build<T>();
}
return out;
}
/// Generate complex pseudo-random data of a specific type in a vector
/// @tparam T - data type held vector
/// @tparam Callback - callback that takes in a DataBuilder* and returns a T
/// @param generate - callback for generating each instance of T
/// @returns pseudo-random data of type std::vector<T>
template <typename T, typename Callback>
std::vector<T> vector(Callback generate) {
auto count = build<uint8_t>();
std::vector<T> out(count);
for (size_t i = 0; i < count; i++) {
out[i] = generate(this);
}
return out;
}
/// Generate an pseudo-random entry to a enum class.
/// Assumes enum is tightly packed starting at 0.
/// @tparam T - type of enum class
/// @param count - number of entries in enum class
/// @returns a random enum class entry
template <typename T>
T enum_class(uint32_t count) {
return static_cast<T>(generator_.Get4Bytes() % count);
}
private:
RandomGenerator generator_;
// Disallow copy & assign
DataBuilder(const DataBuilder&) = delete;
DataBuilder& operator=(const DataBuilder&) = delete;
/// Get N bytes of pseudo-random data
/// @param out - pointer to location to save data
/// @param n - number of bytes to get
void build(void* out, size_t n) {
assert(out != nullptr && "|out| cannot be nullptr");
assert(n > 0 && "|n| must be > 0");
generator_.GetNBytes(reinterpret_cast<uint8_t*>(out), n);
}
/// Generate pseudo-random data of a specific type into an output var
/// @tparam T - type of data to produce
/// @param out - output var to generate into
template <typename T>
void build(T& out) {
out = build<T>();
}
/// Implementation of ::build<T>()
/// @tparam T - type of data to produce
template <typename T>
struct BuildImpl {
/// Generate a pseudo-random variable of type T
/// @param b - data builder to use
/// @returns a variable of type T filled with pseudo-random data
static T impl(DataBuilder* b) {
T out{};
b->build(&out, sizeof(T));
return out;
}
};
/// Specialization for std::string
template <>
struct BuildImpl<std::string> {
/// Generate a pseudo-random string
/// @param b - data builder to use
/// @returns a string filled with pseudo-random data
static std::string impl(DataBuilder* b) {
auto count = b->build<uint8_t>();
if (count == 0) {
return "";
}
std::vector<uint8_t> source(count);
b->build(source.data(), count);
return {source.begin(), source.end()};
}
};
/// Specialization for bool
template <>
struct BuildImpl<bool> {
/// Generate a pseudo-random bool
/// @param b - data builder to use
/// @returns a boolean with even odds of being true or false
static bool impl(DataBuilder* b) { return b->generator_.GetBool(); }
};
/// Specialization for writer::msl::Options
template <>
struct BuildImpl<writer::msl::Options> {
/// Generate a pseudo-random writer::msl::Options struct
/// @param b - data builder to use
/// @returns writer::msl::Options filled with pseudo-random data
static writer::msl::Options impl(DataBuilder* b) {
writer::msl::Options out{};
b->build(out.buffer_size_ubo_index);
b->build(out.fixed_sample_mask);
b->build(out.emit_vertex_point_size);
b->build(out.disable_workgroup_init);
b->build(out.array_length_from_uniform);
return out;
}
};
/// Specialization for writer::hlsl::Options
template <>
struct BuildImpl<writer::hlsl::Options> {
/// Generate a pseudo-random writer::hlsl::Options struct
/// @param b - data builder to use
/// @returns writer::hlsl::Options filled with pseudo-random data
static writer::hlsl::Options impl(DataBuilder* b) {
writer::hlsl::Options out{};
b->build(out.root_constant_binding_point);
b->build(out.disable_workgroup_init);
b->build(out.array_length_from_uniform);
return out;
}
};
/// Specialization for writer::spirv::Options
template <>
struct BuildImpl<writer::spirv::Options> {
/// Generate a pseudo-random writer::spirv::Options struct
/// @param b - data builder to use
/// @returns writer::spirv::Options filled with pseudo-random data
static writer::spirv::Options impl(DataBuilder* b) {
writer::spirv::Options out{};
b->build(out.emit_vertex_point_size);
b->build(out.disable_workgroup_init);
return out;
}
};
/// Specialization for writer::ArrayLengthFromUniformOptions
template <>
struct BuildImpl<writer::ArrayLengthFromUniformOptions> {
/// Generate a pseudo-random writer::ArrayLengthFromUniformOptions struct
/// @param b - data builder to use
/// @returns writer::ArrayLengthFromUniformOptions filled with pseudo-random
/// data
static writer::ArrayLengthFromUniformOptions impl(DataBuilder* b) {
writer::ArrayLengthFromUniformOptions out{};
b->build(out.ubo_binding);
b->build(out.bindpoint_to_size_index);
return out;
}
};
/// Specialization for std::unordered_map<K, V>
template <typename K, typename V>
struct BuildImpl<std::unordered_map<K, V>> {
/// Generate a pseudo-random std::unordered_map<K, V>
/// @param b - data builder to use
/// @returns std::unordered_map<K, V> filled with
/// pseudo-random data
static std::unordered_map<K, V> impl(DataBuilder* b) {
std::unordered_map<K, V> out;
uint8_t count = b->build<uint8_t>();
for (uint8_t i = 0; i < count; ++i) {
out.emplace(b->build<K>(), b->build<V>());
}
return out;
}
};
};
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_DATA_BUILDER_H_

View File

@ -1,112 +0,0 @@
"&"
"&&"
"->"
"[["
"]]"
"/"
"!"
"["
"]"
"{"
"}"
":"
","
"="
"=="
">"
">="
"<"
"<="
"%"
"-"
"::"
"!="
"."
"+"
"|"
"||"
"("
")"
";"
"*"
"^"
"array"
"binding"
"bitcast"
"bool"
"block"
"break"
"builtin"
"case"
"compute"
"const"
"continue"
"continuing"
"discard"
"default"
"else"
"elseif"
"f32"
"fallthrough"
"false"
"fn"
"fragment"
"function"
"i32"
"if"
"image"
"import"
"in"
"location"
"loop"
"mat2x2"
"mat2x3"
"mat2x4"
"mat3x2"
"mat3x3"
"mat3x4"
"mat4x2"
"mat4x3"
"mat4x4"
"offset"
"out"
"private"
"ptr"
"return"
"sampler"
"sampler_comparison"
"set"
"storage"
"stage"
"stride"
"struct"
"switch"
"texture_depth_2d"
"texture_depth_2d_array"
"texture_depth_cube"
"texture_depth_cube_array"
"texture_depth_multisampled_2d"
"texture_multisampled_2d"
"texture_storage_1d"
"texture_storage_2d_array"
"texture_storage_2d"
"texture_storage_2d_array"
"texture_storage_3d"
"texture_1d"
"texture_2d"
"texture_2d_array"
"texture_3d"
"texture_cube"
"texture_cube_array"
"true"
"type"
"u32"
"uniform"
"var"
"vec2"
"vec3"
"vec4"
"vertex"
"void"
"workgroup"
"workgroup_size"

View File

@ -1,35 +0,0 @@
// 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 "fuzzers/fuzzer_init.h"
#include "fuzzers/cli.h"
namespace tint {
namespace fuzzers {
namespace {
CliParams cli_params;
}
const CliParams& GetCliParams() {
return cli_params;
}
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
cli_params = ParseCliParams(argc, *argv);
return 0;
}
} // namespace fuzzers
} // namespace tint

View File

@ -1,29 +0,0 @@
// 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.
#ifndef FUZZERS_FUZZER_INIT_H_
#define FUZZERS_FUZZER_INIT_H_
#include "fuzzers/cli.h"
namespace tint {
namespace fuzzers {
/// Returns the common CliParams parsed and populated by LLVMFuzzerInitialize()
const CliParams& GetCliParams();
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_FUZZER_INIT_H_

View File

@ -1,92 +0,0 @@
#!/usr/bin/env python3
# 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.
# Collect all .spvasm files under a given directory, assemble them using
# spirv-as, and emit the assembled binaries to a given corpus directory,
# flattening their file names by replacing path separators with underscores.
# If the output directory already exists, it will be deleted and re-created.
# Files ending with ".expected.spvasm" are skipped.
#
# The intended use of this script is to generate a corpus of SPIR-V
# binaries for fuzzing.
#
# Usage:
# generate_spirv_corpus.py <input_dir> <corpus_dir> <path to spirv-as>
import os
import pathlib
import shutil
import subprocess
import sys
def list_spvasm_files(root_search_dir):
for root, folders, files in os.walk(root_search_dir):
for filename in folders + files:
if pathlib.Path(filename).suffix == ".spvasm":
yield os.path.join(root, filename)
def main():
if len(sys.argv) != 4:
print("Usage: " + sys.argv[0] +
" <input dir> <output dir> <spirv-as path>")
return 1
input_dir: str = os.path.abspath(sys.argv[1].rstrip(os.sep))
corpus_dir: str = os.path.abspath(sys.argv[2])
spirv_as_path: str = os.path.abspath(sys.argv[3])
if os.path.exists(corpus_dir):
shutil.rmtree(corpus_dir)
os.makedirs(corpus_dir)
# It might be that some of the attempts to convert SPIR-V assembly shaders
# into SPIR-V binaries go wrong. It is sensible to tolerate a small number
# of such errors, to avoid fuzzer preparation failing due to bugs in
# spirv-as. But it is important to know when a large number of failures
# occur, in case something is more deeply wrong.
num_errors = 0
max_tolerated_errors = 10
logged_errors = ""
for in_file in list_spvasm_files(input_dir):
if in_file.endswith(".expected.spvasm"):
continue
out_file = os.path.splitext(corpus_dir + os.sep +
in_file[len(input_dir) + 1:]
.replace(os.sep, '_'))[0] + ".spv"
cmd = [spirv_as_path,
"--target-env",
"spv1.3",
in_file,
"-o",
out_file]
proc = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()
if proc.returncode != 0:
num_errors += 1
logged_errors += "Error running " + " ".join(cmd) + ": " + stdout.decode('utf-8') + stderr.decode('utf-8')
if num_errors > max_tolerated_errors:
print("Too many (" + str(num_errors) + ") errors occured while generating the SPIR-V corpus.")
print(logged_errors)
return 1
if __name__ == "__main__":
sys.exit(main())

View File

@ -1,60 +0,0 @@
#!/usr/bin/env python3
# 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.
# Collect all .wgsl files under a given directory and copy them to a given
# corpus directory, flattening their file names by replacing path
# separators with underscores. If the output directory already exists, it
# will be deleted and re-created. Files ending with ".expected.spvasm" are
# skipped.
#
# The intended use of this script is to generate a corpus of WGSL shaders
# for fuzzing.
#
# Usage:
# generate_wgsl_corpus.py <input_dir> <corpus_dir>
import os
import pathlib
import shutil
import sys
def list_wgsl_files(root_search_dir):
for root, folders, files in os.walk(root_search_dir):
for filename in folders + files:
if pathlib.Path(filename).suffix == '.wgsl':
yield os.path.join(root, filename)
def main():
if len(sys.argv) != 3:
print("Usage: " + sys.argv[0] + " <input dir> <output dir>")
return 1
input_dir: str = os.path.abspath(sys.argv[1].rstrip(os.sep))
corpus_dir: str = os.path.abspath(sys.argv[2])
if os.path.exists(corpus_dir):
shutil.rmtree(corpus_dir)
os.makedirs(corpus_dir)
for in_file in list_wgsl_files(input_dir):
if in_file.endswith(".expected.wgsl"):
continue
out_file = in_file[len(input_dir) + 1:].replace(os.sep, '_')
shutil.copy(in_file, corpus_dir + os.sep + out_file)
if __name__ == "__main__":
sys.exit(main())

View File

@ -1,59 +0,0 @@
// 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 "fuzzers/mersenne_twister_engine.h"
#include <algorithm>
#include <cassert>
#include "src/utils/hash.h"
namespace tint {
namespace fuzzers {
namespace {
/// Generate integer from uniform distribution
/// @tparam I - integer type
/// @param engine - random number engine to use
/// @param lower - Lower bound of integer generated
/// @param upper - Upper bound of integer generated
/// @returns i, where lower <= i < upper
template <typename I>
I RandomInteger(std::mt19937_64* engine, I lower, I upper) {
assert(lower < upper && "|lower| must be strictly less than |upper|");
return std::uniform_int_distribution<I>(lower, upper - 1)(*engine);
}
} // namespace
MersenneTwisterEngine::MersenneTwisterEngine(uint64_t seed) : engine_(seed) {}
uint32_t MersenneTwisterEngine::RandomUInt32(uint32_t lower, uint32_t upper) {
return RandomInteger(&engine_, lower, upper);
}
uint64_t MersenneTwisterEngine::RandomUInt64(uint64_t lower, uint64_t upper) {
return RandomInteger(&engine_, lower, upper);
}
void MersenneTwisterEngine::RandomNBytes(uint8_t* dest, size_t n) {
assert(dest && "|dest| must not be nullptr");
std::generate(
dest, dest + n,
std::independent_bits_engine<std::mt19937_64, 8, uint8_t>(engine_));
}
} // namespace fuzzers
} // namespace tint

View File

@ -1,62 +0,0 @@
// 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.
#ifndef FUZZERS_MERSENNE_TWISTER_ENGINE_H_
#define FUZZERS_MERSENNE_TWISTER_ENGINE_H_
#include <random>
#include "fuzzers/random_generator_engine.h"
namespace tint {
namespace fuzzers {
/// Standard MT based random number generation
class MersenneTwisterEngine : public RandomGeneratorEngine {
public:
/// @brief Initializes using provided seed
/// @param seed - seed value to use
explicit MersenneTwisterEngine(uint64_t seed);
~MersenneTwisterEngine() override = default;
/// Generate random uint32_t value from uniform distribution.
/// @param lower - lower bound of integer generated
/// @param upper - upper bound of integer generated
/// @returns i, where lower <= i < upper
uint32_t RandomUInt32(uint32_t lower, uint32_t upper) override;
/// Get random uint64_t value from uniform distribution.
/// @param lower - lower bound of integer generated
/// @param upper - upper bound of integer generated
/// @returns i, where lower <= i < upper
uint64_t RandomUInt64(uint64_t lower, uint64_t upper) override;
/// Get N bytes of pseudo-random data
/// @param dest - memory location to store data
/// @param n - number of bytes of data to generate
void RandomNBytes(uint8_t* dest, size_t n) override;
private:
// Disallow copy & assign
MersenneTwisterEngine(const MersenneTwisterEngine&) = delete;
MersenneTwisterEngine& operator=(const MersenneTwisterEngine&) = delete;
std::mt19937_64 engine_;
}; // class MersenneTwisterEngine
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_MERSENNE_TWISTER_ENGINE_H_

View File

@ -1,124 +0,0 @@
// 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 "fuzzers/random_generator.h"
#include <algorithm>
#include <cassert>
#include <utility>
#include "fuzzers/mersenne_twister_engine.h"
#include "fuzzers/random_generator_engine.h"
#include "src/utils/hash.h"
namespace tint {
namespace fuzzers {
namespace {
/// Calculate the hash for the contents of a c-style data buffer
/// This is intentionally not implemented as a generic override of HashCombine
/// in "src/utils/hash.h", because it conflicts with the vardiac override for
/// the case where a pointer and an integer are being hashed.
/// @param data - pointer to buffer to be hashed
/// @param size - number of elements in buffer
/// @returns hash of the data in the buffer
size_t HashBuffer(const uint8_t* data, const size_t size) {
size_t hash = 102931;
utils::HashCombine(&hash, size);
for (size_t i = 0; i < size; i++) {
utils::HashCombine(&hash, data[i]);
}
return hash;
}
} // namespace
RandomGenerator::RandomGenerator(std::unique_ptr<RandomGeneratorEngine> engine)
: engine_(std::move(engine)) {}
RandomGenerator::RandomGenerator(uint64_t seed)
: RandomGenerator(std::make_unique<MersenneTwisterEngine>(seed)) {}
uint32_t RandomGenerator::GetUInt32(uint32_t lower, uint32_t upper) {
assert(lower < upper && "|lower| must be strictly less than |upper|");
return engine_->RandomUInt32(lower, upper);
}
uint32_t RandomGenerator::GetUInt32(uint32_t bound) {
assert(bound > 0 && "|bound| must be greater than 0");
return engine_->RandomUInt32(0u, bound);
}
uint64_t RandomGenerator::GetUInt64(uint64_t lower, uint64_t upper) {
assert(lower < upper && "|lower| must be strictly less than |upper|");
return engine_->RandomUInt64(lower, upper);
}
uint64_t RandomGenerator::GetUInt64(uint64_t bound) {
assert(bound > 0 && "|bound| must be greater than 0");
return engine_->RandomUInt64(static_cast<uint64_t>(0), bound);
}
uint8_t RandomGenerator::GetByte() {
uint8_t result;
engine_->RandomNBytes(&result, 1);
return result;
}
uint32_t RandomGenerator::Get4Bytes() {
uint32_t result;
engine_->RandomNBytes(reinterpret_cast<uint8_t*>(&result), 4);
return result;
}
void RandomGenerator::GetNBytes(uint8_t* dest, size_t n) {
assert(dest && "|dest| must not be nullptr");
engine_->RandomNBytes(dest, n);
}
bool RandomGenerator::GetBool() {
return engine_->RandomUInt32(0u, 2u);
}
bool RandomGenerator::GetWeightedBool(uint32_t percentage) {
static const uint32_t kMaxPercentage = 100;
assert(percentage <= kMaxPercentage &&
"|percentage| needs to be within [0, 100]");
return engine_->RandomUInt32(0u, kMaxPercentage) < percentage;
}
uint64_t RandomGenerator::CalculateSeed(const uint8_t* data, size_t size) {
assert(data != nullptr && "|data| must be !nullptr");
// Number of bytes we want to skip at the start of data for the hash.
// Fewer bytes may be skipped when `size` is small.
// Has lower precedence than kHashDesiredMinBytes.
static const int64_t kHashDesiredLeadingSkipBytes = 5;
// Minimum number of bytes we want to use in the hash.
// Used for short buffers.
static const int64_t kHashDesiredMinBytes = 4;
// Maximum number of bytes we want to use in the hash.
static const int64_t kHashDesiredMaxBytes = 32;
auto size_i64 = static_cast<int64_t>(size);
auto hash_begin_i64 =
std::min(kHashDesiredLeadingSkipBytes,
std::max<int64_t>(size_i64 - kHashDesiredMinBytes, 0));
auto hash_end_i64 = std::min(hash_begin_i64 + kHashDesiredMaxBytes, size_i64);
auto hash_begin = static_cast<size_t>(hash_begin_i64);
auto hash_size = static_cast<size_t>(hash_end_i64) - hash_begin;
return HashBuffer(data + hash_begin, hash_size);
}
} // namespace fuzzers
} // namespace tint

View File

@ -1,115 +0,0 @@
// 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.
#ifndef FUZZERS_RANDOM_GENERATOR_H_
#define FUZZERS_RANDOM_GENERATOR_H_
#include <memory>
#include <random>
#include <vector>
#include "fuzzers/random_generator_engine.h"
namespace tint {
namespace fuzzers {
/// Pseudo random generator utility class for fuzzing
class RandomGenerator {
public:
/// @brief Initializes using provided engine
/// @param engine - engine implementation to use
explicit RandomGenerator(std::unique_ptr<RandomGeneratorEngine> engine);
/// @brief Creates a MersenneTwisterEngine and initializes using that
/// @param seed - seed value to use for engine
explicit RandomGenerator(uint64_t seed);
~RandomGenerator() = default;
RandomGenerator(RandomGenerator&&) = default;
/// Get uint32_t value from uniform distribution.
/// @param lower - lower bound of integer generated
/// @param upper - upper bound of integer generated
/// @returns i, where lower <= i < upper
uint32_t GetUInt32(uint32_t lower, uint32_t upper);
/// Get uint32_t value from uniform distribution.
/// @param bound - Upper bound of integer generated
/// @returns i, where 0 <= i < bound
uint32_t GetUInt32(uint32_t bound);
/// Get uint32_t value from uniform distribution.
/// @param lower - lower bound of integer generated
/// @param upper - upper bound of integer generated
/// @returns i, where lower <= i < upper
uint64_t GetUInt64(uint64_t lower, uint64_t upper);
/// Get uint64_t value from uniform distribution.
/// @param bound - Upper bound of integer generated
/// @returns i, where 0 <= i < bound
uint64_t GetUInt64(uint64_t bound);
/// Get 1 byte of pseudo-random data
/// Should be more efficient then calling GetNBytes(1);
/// @returns 1-byte of random data
uint8_t GetByte();
/// Get 4 bytes of pseudo-random data
/// Should be more efficient then calling GetNBytes(4);
/// @returns 4-bytes of random data
uint32_t Get4Bytes();
/// Get N bytes of pseudo-random data
/// @param dest - memory location to store data
/// @param n - number of bytes of data to get
void GetNBytes(uint8_t* dest, size_t n);
/// Get random bool with even odds
/// @returns true 50% of the time and false %50 of time.
bool GetBool();
/// Get random bool with weighted odds
/// @param percentage - likelihood of true being returned
/// @returns true |percentage|% of the time, and false (100 - |percentage|)%
/// of the time.
bool GetWeightedBool(uint32_t percentage);
/// Returns a randomly-chosen element from vector v.
/// @param v - the vector from which the random element will be selected.
/// @return a random element of vector v.
template <typename T>
inline T GetRandomElement(const std::vector<T>& v) {
return v[GetUInt64(0, v.size())];
}
/// Calculate a seed value based on a blob of data.
/// Currently hashes bytes near the front of the buffer, after skipping N
/// bytes.
/// @param data - pointer to data to base calculation off of, must be !nullptr
/// @param size - number of elements in |data|, must be > 0
static uint64_t CalculateSeed(const uint8_t* data, size_t size);
private:
// Disallow copy & assign
RandomGenerator(const RandomGenerator&) = delete;
RandomGenerator& operator=(const RandomGenerator&) = delete;
std::unique_ptr<RandomGeneratorEngine> engine_;
}; // class RandomGenerator
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_RANDOM_GENERATOR_H_

View File

@ -1,26 +0,0 @@
// 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 "fuzzers/random_generator_engine.h"
namespace tint {
namespace fuzzers {
// Not in header to avoid weak vtable warnings from clang
RandomGeneratorEngine::RandomGeneratorEngine() = default;
RandomGeneratorEngine::~RandomGeneratorEngine() = default;
RandomGeneratorEngine::RandomGeneratorEngine(RandomGeneratorEngine&&) = default;
} // namespace fuzzers
} // namespace tint

View File

@ -1,58 +0,0 @@
// 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.
#ifndef FUZZERS_RANDOM_GENERATOR_ENGINE_H_
#define FUZZERS_RANDOM_GENERATOR_ENGINE_H_
#include <memory>
#include <random>
#include <vector>
namespace tint {
namespace fuzzers {
/// Wrapper interface around STL random number engine
class RandomGeneratorEngine {
public:
RandomGeneratorEngine();
virtual ~RandomGeneratorEngine();
RandomGeneratorEngine(RandomGeneratorEngine&&);
/// Generate random uint32_t value from uniform distribution.
/// @param lower - lower bound of integer generated
/// @param upper - upper bound of integer generated
/// @returns i, where lower <= i < upper
virtual uint32_t RandomUInt32(uint32_t lower, uint32_t upper) = 0;
/// Get random uint64_t value from uniform distribution.
/// @param lower - lower bound of integer generated
/// @param upper - upper bound of integer generated
/// @returns i, where lower <= i < upper
virtual uint64_t RandomUInt64(uint64_t lower, uint64_t upper) = 0;
/// Get N bytes of pseudo-random data
/// @param dest - memory location to store data
/// @param n - number of bytes of data to generate
virtual void RandomNBytes(uint8_t* dest, size_t n) = 0;
private:
// Disallow copy & assign
RandomGeneratorEngine(const RandomGeneratorEngine&) = delete;
RandomGeneratorEngine& operator=(const RandomGeneratorEngine&) = delete;
}; // class RandomGeneratorEngine
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_RANDOM_GENERATOR_ENGINE_H_

View File

@ -1,202 +0,0 @@
// 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 "fuzzers/random_generator.h"
#include <memory>
#include "gtest/gtest.h"
#include "fuzzers/mersenne_twister_engine.h"
namespace tint {
namespace fuzzers {
namespace {
/// Implementation of RandomGeneratorEngine that just returns a stream of
/// monotonically increasing numbers.
class MonotonicEngine : public RandomGeneratorEngine {
public:
uint32_t RandomUInt32(uint32_t, uint32_t) override { return next_++; }
uint64_t RandomUInt64(uint64_t, uint64_t) override { return next_++; }
void RandomNBytes(uint8_t*, size_t) override {
assert(false && "MonotonicDelegate does not implement RandomNBytes");
}
private:
uint32_t next_ = 0;
};
class RandomGeneratorTest : public testing::Test {
public:
void SetUp() override { rng_ = std::make_unique<RandomGenerator>(0); }
void TearDown() override {}
protected:
std::unique_ptr<RandomGenerator> rng_;
};
#ifndef NDEBUG
TEST_F(RandomGeneratorTest, GetUInt32ReversedBoundsCrashes) {
EXPECT_DEATH(rng_->GetUInt32(10, 5), ".*");
}
TEST_F(RandomGeneratorTest, GetUInt32EmptyBoundsCrashes) {
EXPECT_DEATH(rng_->GetUInt32(5, 5), ".*");
}
TEST_F(RandomGeneratorTest, GetUInt32ZeroBoundCrashes) {
EXPECT_DEATH(rng_->GetUInt32(0u), ".*");
}
#endif // NDEBUG
TEST_F(RandomGeneratorTest, GetUInt32SingularReturnsOneValue) {
{
uint32_t result = rng_->GetUInt32(5u, 6u);
ASSERT_EQ(5u, result);
}
{
uint32_t result = rng_->GetUInt32(1u);
ASSERT_EQ(0u, result);
}
}
TEST_F(RandomGeneratorTest, GetUInt32StaysInBounds) {
{
uint32_t result = rng_->GetUInt32(5u, 10u);
ASSERT_LE(5u, result);
ASSERT_GT(10u, result);
}
{
uint32_t result = rng_->GetUInt32(10u);
ASSERT_LE(0u, result);
ASSERT_GT(10u, result);
}
}
#ifndef NDEBUG
TEST_F(RandomGeneratorTest, GetUInt64ReversedBoundsCrashes) {
EXPECT_DEATH(rng_->GetUInt64(10, 5), ".*");
}
TEST_F(RandomGeneratorTest, GetUInt64EmptyBoundsCrashes) {
EXPECT_DEATH(rng_->GetUInt64(5, 5), ".*");
}
TEST_F(RandomGeneratorTest, GetUInt64ZeroBoundCrashes) {
EXPECT_DEATH(rng_->GetUInt64(0u), ".*");
}
#endif // NDEBUG
TEST_F(RandomGeneratorTest, GetUInt64SingularReturnsOneValue) {
{
uint64_t result = rng_->GetUInt64(5u, 6u);
ASSERT_EQ(5u, result);
}
{
uint64_t result = rng_->GetUInt64(1u);
ASSERT_EQ(0u, result);
}
}
TEST_F(RandomGeneratorTest, GetUInt64StaysInBounds) {
{
uint64_t result = rng_->GetUInt64(5u, 10u);
ASSERT_LE(5u, result);
ASSERT_GT(10u, result);
}
{
uint64_t result = rng_->GetUInt64(10u);
ASSERT_LE(0u, result);
ASSERT_GT(10u, result);
}
}
TEST_F(RandomGeneratorTest, GetByte) {
rng_->GetByte();
}
#ifndef NDEBUG
TEST_F(RandomGeneratorTest, GetNBytesNullDataBufferCrashes) {
EXPECT_DEATH(rng_->GetNBytes(nullptr, 5), ".*");
}
#endif // NDEBUG
TEST_F(RandomGeneratorTest, GetNBytes) {
std::vector<uint8_t> data;
for (uint32_t i = 25; i < 1000u; i = i + 25) {
data.resize(i);
rng_->GetNBytes(data.data(), data.size());
}
}
TEST_F(RandomGeneratorTest, GetBool) {
rng_->GetBool();
}
TEST_F(RandomGeneratorTest, GetWeightedBoolZeroAlwaysFalse) {
ASSERT_FALSE(rng_->GetWeightedBool(0));
}
TEST_F(RandomGeneratorTest, GetWeightedBoolHundredAlwaysTrue) {
ASSERT_TRUE(rng_->GetWeightedBool(100));
}
#ifndef NDEBUG
TEST_F(RandomGeneratorTest, GetWeightedBoolAboveHundredCrashes) {
EXPECT_DEATH(rng_->GetWeightedBool(101), ".*");
EXPECT_DEATH(rng_->GetWeightedBool(500), ".*");
}
#endif // NDEBUG
TEST_F(RandomGeneratorTest, GetWeightedBool) {
for (uint32_t i = 0; i <= 100; i++) {
rng_ =
std::make_unique<RandomGenerator>(std::make_unique<MonotonicEngine>());
for (uint32_t j = 0; j <= 100; j++) {
if (j < i) {
ASSERT_TRUE(rng_->GetWeightedBool(i));
} else {
ASSERT_FALSE(rng_->GetWeightedBool(i));
}
}
}
}
#ifndef NDEBUG
TEST_F(RandomGeneratorTest, GetRandomElementEmptyVectorCrashes) {
std::vector<uint8_t> v;
EXPECT_DEATH(rng_->GetRandomElement(v), ".*");
}
#endif // NDEBUG
TEST_F(RandomGeneratorTest, GetRandomElement) {
std::vector<uint32_t> v;
for (uint32_t i = 25; i < 100u; i = i + 25) {
rng_ =
std::make_unique<RandomGenerator>(std::make_unique<MonotonicEngine>());
v.resize(i);
std::iota(v.begin(), v.end(), 0);
for (uint32_t j = 0; j < i; j++) {
EXPECT_EQ(j, rng_->GetRandomElement(v));
}
}
}
} // namespace
} // namespace fuzzers
} // namespace tint

View File

@ -1,38 +0,0 @@
// Copyright 2022 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 "fuzzers/shuffle_transform.h"
#include <random>
#include "src/program_builder.h"
namespace tint {
namespace fuzzers {
ShuffleTransform::ShuffleTransform(size_t seed) : seed_(seed) {}
void ShuffleTransform::Run(CloneContext& ctx,
const tint::transform::DataMap&,
tint::transform::DataMap&) const {
auto decls = ctx.src->AST().GlobalDeclarations();
auto rng = std::mt19937_64{seed_};
std::shuffle(std::begin(decls), std::end(decls), rng);
for (auto* decl : decls) {
ctx.dst->AST().AddGlobalDeclaration(ctx.Clone(decl));
}
}
} // namespace fuzzers
} // namespace tint

View File

@ -1,42 +0,0 @@
// Copyright 2022 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.
#ifndef FUZZERS_SHUFFLE_TRANSFORM_H_
#define FUZZERS_SHUFFLE_TRANSFORM_H_
#include "src/transform/transform.h"
namespace tint {
namespace fuzzers {
/// ShuffleTransform reorders the module scope declarations into a random order
class ShuffleTransform : public tint::transform::Transform {
public:
/// Constructor
/// @param seed the random seed to use for the shuffling
explicit ShuffleTransform(size_t seed);
protected:
void Run(CloneContext& ctx,
const tint::transform::DataMap&,
tint::transform::DataMap&) const override;
private:
size_t seed_;
};
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_SHUFFLE_TRANSFORM_H_

View File

@ -1,85 +0,0 @@
// 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 "fuzzers/fuzzer_init.h"
#include "fuzzers/random_generator.h"
#include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/transform_builder.h"
namespace tint {
namespace fuzzers {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
{
TransformBuilder tb(data, size);
tb.AddTransform<ShuffleTransform>();
tb.AddPlatformIndependentPasses();
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
fuzzer.SetDumpInput(GetCliParams().dump_input);
fuzzer.SetEnforceValidity(GetCliParams().enforce_validity);
fuzzer.Run(data, size);
}
#if TINT_BUILD_HLSL_WRITER
{
TransformBuilder tb(data, size);
tb.AddTransform<ShuffleTransform>();
tb.AddPlatformIndependentPasses();
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kHLSL);
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
fuzzer.SetDumpInput(GetCliParams().dump_input);
fuzzer.SetEnforceValidity(GetCliParams().enforce_validity);
fuzzer.Run(data, size);
}
#endif // TINT_BUILD_HLSL_WRITER
#if TINT_BUILD_MSL_WRITER
{
TransformBuilder tb(data, size);
tb.AddTransform<ShuffleTransform>();
tb.AddPlatformIndependentPasses();
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kMSL);
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
fuzzer.SetDumpInput(GetCliParams().dump_input);
fuzzer.SetEnforceValidity(GetCliParams().enforce_validity);
fuzzer.Run(data, size);
}
#endif // TINT_BUILD_MSL_WRITER
#if TINT_BUILD_SPV_WRITER
{
TransformBuilder tb(data, size);
tb.AddTransform<ShuffleTransform>();
tb.AddPlatformIndependentPasses();
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kSpv);
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
fuzzer.SetDumpInput(GetCliParams().dump_input);
fuzzer.SetEnforceValidity(GetCliParams().enforce_validity);
fuzzer.Run(data, size);
}
#endif // TINT_BUILD_SPV_WRITER
return 0;
}
} // namespace fuzzers
} // namespace tint

View File

@ -1,116 +0,0 @@
// Copyright 2020 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 <iostream>
#include <string>
#include <unordered_set>
#include "src/reader/wgsl/parser_impl.h"
#include "src/writer/wgsl/generator.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::diag::List& diagnostics) {
auto printer = tint::diag::Printer::create(stderr, true);
tint::diag::Formatter{}.format(diagnostics, printer.get());
__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::reader::wgsl::ParserImpl 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::sem::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::writer::wgsl::Options wgsl_options;
{
auto result = tint::writer::wgsl::Generate(&src, wgsl_options);
ASSERT_TRUE(result.success);
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::writer::wgsl::Generate(&dst, wgsl_options);
ASSERT_TRUE(result.success);
auto dst_wgsl = result.wgsl;
ASSERT_EQ(src_wgsl, dst_wgsl);
return 0;
}

View File

@ -1,111 +0,0 @@
# 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.
function(add_tint_ast_fuzzer NAME)
add_executable(${NAME} ${NAME}.cc ${AST_FUZZER_SOURCES})
target_link_libraries(${NAME} libtint-fuzz libtint_ast_fuzzer)
tint_default_compile_options(${NAME})
target_compile_definitions(${NAME} PRIVATE CUSTOM_MUTATOR)
target_include_directories(${NAME} PRIVATE ${CMAKE_BINARY_DIR})
endfunction()
set(PROTOBUF_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/protobufs/tint_ast_fuzzer.proto)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/protobufs)
add_custom_command(
OUTPUT
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.cc
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.h
COMMAND
"protobuf::protoc" -I=${CMAKE_CURRENT_SOURCE_DIR}/protobufs
--cpp_out=${CMAKE_CURRENT_BINARY_DIR}/protobufs ${PROTOBUF_SOURCES}
DEPENDS ${PROTOBUF_SOURCES}
COMMENT "Generate protobuf sources from proto definition file.")
set(LIBTINT_AST_FUZZER_SOURCES
../mersenne_twister_engine.h
../random_generator.h
../random_generator_engine.h
mutation.h
mutation_finder.h
mutation_finders/replace_identifiers.h
mutations/replace_identifier.h
mutator.h
node_id_map.h
probability_context.h
protobufs/tint_ast_fuzzer.h
util.h
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.h)
set(LIBTINT_AST_FUZZER_SOURCES ${LIBTINT_AST_FUZZER_SOURCES}
../mersenne_twister_engine.cc
../random_generator.cc
../random_generator_engine.cc
mutation.cc
mutation_finder.cc
mutation_finders/replace_identifiers.cc
mutations/replace_identifier.cc
mutator.cc
node_id_map.cc
probability_context.cc
${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.cc)
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/protobufs/tint_ast_fuzzer.pb.cc PROPERTIES COMPILE_FLAGS -w)
# Add static library target.
add_library(libtint_ast_fuzzer STATIC ${LIBTINT_AST_FUZZER_SOURCES})
target_link_libraries(libtint_ast_fuzzer protobuf::libprotobuf libtint)
tint_default_compile_options(libtint_ast_fuzzer)
target_include_directories(libtint_ast_fuzzer PRIVATE ${CMAKE_BINARY_DIR})
set(AST_FUZZER_SOURCES
cli.cc
cli.h
fuzzer.cc
override_cli_params.h
../tint_common_fuzzer.cc
../tint_common_fuzzer.h)
set_source_files_properties(fuzzer.cc PROPERTIES COMPILE_FLAGS -Wno-missing-prototypes)
# Add libfuzzer targets.
# Targets back-ends according to command line arguments.
add_tint_ast_fuzzer(tint_ast_fuzzer)
# Targets back-ends individually.
add_tint_ast_fuzzer(tint_ast_hlsl_writer_fuzzer)
add_tint_ast_fuzzer(tint_ast_msl_writer_fuzzer)
add_tint_ast_fuzzer(tint_ast_spv_writer_fuzzer)
add_tint_ast_fuzzer(tint_ast_wgsl_writer_fuzzer)
# Add tests.
if (${TINT_BUILD_TESTS})
set(TEST_SOURCES
mutations/replace_identifier_test.cc)
add_executable(tint_ast_fuzzer_unittests ${TEST_SOURCES})
target_include_directories(
tint_ast_fuzzer_unittests PRIVATE ${gmock_SOURCE_DIR}/include)
target_link_libraries(tint_ast_fuzzer_unittests gmock_main libtint_ast_fuzzer)
tint_default_compile_options(tint_ast_fuzzer_unittests)
target_compile_options(tint_ast_fuzzer_unittests PRIVATE
-Wno-global-constructors
-Wno-weak-vtables
-Wno-covered-switch-default)
target_include_directories(tint_ast_fuzzer_unittests PRIVATE ${CMAKE_BINARY_DIR})
add_test(NAME tint_ast_fuzzer_unittests COMMAND tint_ast_fuzzer_unittests)
endif ()

View File

@ -1,167 +0,0 @@
// 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 "fuzzers/tint_ast_fuzzer/cli.h"
#include <cstring>
#include <iostream>
#include <limits>
#include <sstream>
#include <string>
#include <utility>
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
namespace {
const char* const kHelpMessage = R"(
This is a fuzzer for the Tint compiler that works by mutating the AST.
Below is a list of all supported parameters for this fuzzer. You may want to
run it with -help=1 to check out libfuzzer parameters.
-tint_enable_all_mutations=
If `false`, the fuzzer will only apply mutations from a
randomly selected subset of mutation types. Otherwise,
all mutation types will be considered. This must be one
of `true` or `false` (without `). By default it's `false`.
-tint_fuzzing_target=
Specifies the shading language to target during fuzzing.
This must be one or a combination of `wgsl`, `spv`, `hlsl`,
`msl` (without `) separated by commas. By default it's
`wgsl,msl,hlsl,spv`.
-tint_help
Show this message. Note that there is also a -help=1
parameter that will display libfuzzer's help message.
-tint_mutation_batch_size=
The number of mutations to apply in a single libfuzzer
mutation session. This must be a numeric value that fits
in type `uint32_t`. By default it's 5.
)";
bool HasPrefix(const char* str, const char* prefix) {
return strncmp(str, prefix, strlen(prefix)) == 0;
}
[[noreturn]] void InvalidParam(const char* param) {
std::cout << "Invalid value for " << param << std::endl;
std::cout << kHelpMessage << std::endl;
exit(1);
}
bool ParseBool(const char* value, bool* out) {
if (!strcmp(value, "true")) {
*out = true;
} else if (!strcmp(value, "false")) {
*out = false;
} else {
return false;
}
return true;
}
bool ParseUint32(const char* value, uint32_t* out) {
auto parsed = strtoul(value, nullptr, 10);
if (parsed > std::numeric_limits<uint32_t>::max()) {
return false;
}
*out = static_cast<uint32_t>(parsed);
return true;
}
bool ParseFuzzingTarget(const char* value, FuzzingTarget* out) {
if (!strcmp(value, "wgsl")) {
*out = FuzzingTarget::kWgsl;
} else if (!strcmp(value, "spv")) {
*out = FuzzingTarget::kSpv;
} else if (!strcmp(value, "msl")) {
*out = FuzzingTarget::kMsl;
} else if (!strcmp(value, "hlsl")) {
*out = FuzzingTarget::kHlsl;
} else {
return false;
}
return true;
}
} // namespace
CliParams ParseCliParams(int* argc, char** argv) {
CliParams cli_params;
auto help = false;
for (int i = *argc - 1; i > 0; --i) {
auto param = argv[i];
auto recognized_parameter = true;
if (HasPrefix(param, "-tint_enable_all_mutations=")) {
if (!ParseBool(param + sizeof("-tint_enable_all_mutations=") - 1,
&cli_params.enable_all_mutations)) {
InvalidParam(param);
}
} else if (HasPrefix(param, "-tint_mutation_batch_size=")) {
if (!ParseUint32(param + sizeof("-tint_mutation_batch_size=") - 1,
&cli_params.mutation_batch_size)) {
InvalidParam(param);
}
} else if (HasPrefix(param, "-tint_fuzzing_target=")) {
auto result = FuzzingTarget::kNone;
std::stringstream ss(param + sizeof("-tint_fuzzing_target=") - 1);
for (std::string value; std::getline(ss, value, ',');) {
auto tmp = FuzzingTarget::kNone;
if (!ParseFuzzingTarget(value.c_str(), &tmp)) {
InvalidParam(param);
}
result = result | tmp;
}
if (result == FuzzingTarget::kNone) {
InvalidParam(param);
}
cli_params.fuzzing_target = result;
} else if (!strcmp(param, "-tint_help")) {
help = true;
} else {
recognized_parameter = false;
}
if (recognized_parameter) {
// Remove the recognized parameter from the list of all parameters by
// swapping it with the last one. This will suppress warnings in the
// libFuzzer about unrecognized parameters. By default, libFuzzer thinks
// that all user-defined parameters start with two dashes. However, we are
// forced to use a single one to make the fuzzer compatible with the
// ClusterFuzz.
std::swap(argv[i], argv[*argc - 1]);
*argc -= 1;
}
}
if (help) {
std::cout << kHelpMessage << std::endl;
exit(0);
}
return cli_params;
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,72 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_AST_FUZZER_CLI_H_
#define FUZZERS_TINT_AST_FUZZER_CLI_H_
#include <cstdint>
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
/// The backend this fuzzer will test.
enum class FuzzingTarget {
kNone = 0,
kHlsl = 1 << 0,
kMsl = 1 << 1,
kSpv = 1 << 2,
kWgsl = 1 << 3,
kAll = kHlsl | kMsl | kSpv | kWgsl
};
inline FuzzingTarget operator|(FuzzingTarget a, FuzzingTarget b) {
return static_cast<FuzzingTarget>(static_cast<int>(a) | static_cast<int>(b));
}
inline FuzzingTarget operator&(FuzzingTarget a, FuzzingTarget b) {
return static_cast<FuzzingTarget>(static_cast<int>(a) & static_cast<int>(b));
}
/// CLI parameters accepted by the fuzzer. Type -tint_help in the CLI to see the
/// help message
struct CliParams {
/// Whether to use all mutation finders or only a randomly selected subset of
/// them.
bool enable_all_mutations = false;
/// The maximum number of mutations applied during a single mutation session
/// (i.e. a call to `ast_fuzzer::Mutate` function).
uint32_t mutation_batch_size = 5;
/// Compiler backends we want to fuzz.
FuzzingTarget fuzzing_target = FuzzingTarget::kAll;
};
/// @brief Parses CLI parameters.
///
/// This function will exit the process with non-zero return code if some
/// parameters are invalid. This function will remove recognized parameters from
/// `argv` and adjust `argc` accordingly.
///
/// @param argc - the total number of parameters.
/// @param argv - array of all CLI parameters.
/// @return parsed parameters.
CliParams ParseCliParams(int* argc, char** argv);
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_AST_FUZZER_CLI_H_

View File

@ -1,134 +0,0 @@
// 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 <cstddef>
#include <cstdint>
#include "fuzzers/random_generator.h"
#include "fuzzers/tint_ast_fuzzer/cli.h"
#include "fuzzers/tint_ast_fuzzer/mutator.h"
#include "fuzzers/tint_ast_fuzzer/override_cli_params.h"
#include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/transform_builder.h"
#include "src/reader/wgsl/parser.h"
#include "src/writer/wgsl/generator.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
namespace {
CliParams cli_params{};
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
// Parse CLI parameters. `ParseCliParams` will call `exit` if some parameter
// is invalid.
cli_params = ParseCliParams(argc, *argv);
// For some fuzz targets it is desirable to force the values of certain CLI
// parameters after parsing.
OverrideCliParams(cli_params);
return 0;
}
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data,
size_t size,
size_t max_size,
unsigned seed) {
Source::File file("test.wgsl", {reinterpret_cast<char*>(data), size});
auto program = reader::wgsl::Parse(&file);
if (!program.IsValid()) {
std::cout << "Trying to mutate an invalid program:" << std::endl
<< program.Diagnostics().str() << std::endl;
return 0;
}
// Run the mutator.
RandomGenerator generator(seed);
ProbabilityContext probability_context(&generator);
program = Mutate(std::move(program), &probability_context,
cli_params.enable_all_mutations,
cli_params.mutation_batch_size, nullptr);
if (!program.IsValid()) {
std::cout << "Mutator produced invalid WGSL:" << std::endl
<< " seed: " << seed << std::endl
<< program.Diagnostics().str() << std::endl;
return 0;
}
auto result = writer::wgsl::Generate(&program, writer::wgsl::Options());
if (!result.success) {
std::cout << "Can't generate WGSL for a valid tint::Program:" << std::endl
<< result.error << std::endl;
return 0;
}
if (result.wgsl.size() > max_size) {
return 0;
}
// No need to worry about the \0 here. The reason is that if \0 is included by
// developer by mistake, it will be considered a part of the string and will
// cause all sorts of strange bugs. Thus, unless `data` below is used as a raw
// C string, the \0 symbol should be ignored.
std::memcpy( // NOLINT - clang-tidy warns about lack of null termination.
data, result.wgsl.data(), result.wgsl.size());
return result.wgsl.size();
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size == 0) {
return 0;
}
struct Target {
FuzzingTarget fuzzing_target;
OutputFormat output_format;
const char* name;
};
Target targets[] = {{FuzzingTarget::kWgsl, OutputFormat::kWGSL, "WGSL"},
{FuzzingTarget::kHlsl, OutputFormat::kHLSL, "HLSL"},
{FuzzingTarget::kMsl, OutputFormat::kMSL, "MSL"},
{FuzzingTarget::kSpv, OutputFormat::kSpv, "SPV"}};
for (auto target : targets) {
if ((target.fuzzing_target & cli_params.fuzzing_target) !=
target.fuzzing_target) {
continue;
}
TransformBuilder tb(data, size);
tb.AddTransform<tint::transform::Robustness>();
CommonFuzzer fuzzer(InputFormat::kWGSL, target.output_format);
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
fuzzer.Run(data, size);
if (fuzzer.HasErrors()) {
std::cout << "Fuzzing " << target.name << " produced an error"
<< std::endl;
auto printer = tint::diag::Printer::create(stderr, true);
tint::diag::Formatter{}.format(fuzzer.Diagnostics(), printer.get());
}
}
return 0;
}
} // namespace
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,42 +0,0 @@
// 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 "fuzzers/tint_ast_fuzzer/mutation.h"
#include <cassert>
#include "fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
Mutation::~Mutation() = default;
std::unique_ptr<Mutation> Mutation::FromMessage(
const protobufs::Mutation& message) {
switch (message.mutation_case()) {
case protobufs::Mutation::kReplaceIdentifier:
return std::make_unique<MutationReplaceIdentifier>(
message.replace_identifier());
case protobufs::Mutation::MUTATION_NOT_SET:
assert(false && "Mutation is not set");
break;
}
return nullptr;
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,86 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_AST_FUZZER_MUTATION_H_
#define FUZZERS_TINT_AST_FUZZER_MUTATION_H_
#include <memory>
#include <vector>
#include "fuzzers/tint_ast_fuzzer/node_id_map.h"
#include "fuzzers/tint_ast_fuzzer/protobufs/tint_ast_fuzzer.h"
#include "src/clone_context.h"
#include "src/program.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
/// The base class for all the mutations in the fuzzer. Children must override
/// three methods:
/// - `IsApplicable` - checks whether it is possible to apply the mutation
/// in a manner that will lead to a valid program.
/// - `Apply` - applies the mutation.
/// - `ToMessage` - converts the mutation data into a protobuf message.
class Mutation {
public:
/// Virtual destructor.
virtual ~Mutation();
/// @brief Determines whether this mutation is applicable to the `program`.
///
/// @param program - the program this mutation will be applied to. The program
/// must be valid.
/// @param node_id_map - the map from `tint::ast::` nodes to their ids.
/// @return `true` if `Apply` method can be called without breaking the
/// semantics of the `program`.
/// @return `false` otherwise.
virtual bool IsApplicable(const tint::Program& program,
const NodeIdMap& node_id_map) const = 0;
/// @brief Applies this mutation to the `clone_context`.
///
/// Precondition: `IsApplicable` must return `true` when invoked on the same
/// `node_id_map` and `clone_context->src` instance of `tint::Program`. A new
/// `tint::Program` that arises in `clone_context` must be valid.
///
/// @param node_id_map - the map from `tint::ast::` nodes to their ids.
/// @param clone_context - the context that will clone the program with some
/// changes introduced by this mutation.
/// @param new_node_id_map - this map will store ids for the mutated and
/// cloned program. This argument cannot be a `nullptr` nor can it point
/// to the same object as `node_id_map`.
virtual void Apply(const NodeIdMap& node_id_map,
tint::CloneContext* clone_context,
NodeIdMap* new_node_id_map) const = 0;
/// @return a protobuf message for this mutation.
virtual protobufs::Mutation ToMessage() const = 0;
/// @brief Converts a protobuf message into the mutation instance.
///
/// @param message - a protobuf message.
/// @return the instance of this class.
static std::unique_ptr<Mutation> FromMessage(
const protobufs::Mutation& message);
};
using MutationList = std::vector<std::unique_ptr<Mutation>>;
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_AST_FUZZER_MUTATION_H_

View File

@ -1,25 +0,0 @@
// 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 "fuzzers/tint_ast_fuzzer/mutation_finder.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
MutationFinder::~MutationFinder() = default;
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,77 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_AST_FUZZER_MUTATION_FINDER_H_
#define FUZZERS_TINT_AST_FUZZER_MUTATION_FINDER_H_
#include <memory>
#include <vector>
#include "fuzzers/tint_ast_fuzzer/mutation.h"
#include "fuzzers/tint_ast_fuzzer/node_id_map.h"
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
#include "src/program.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
/// Instances of this class traverse the `tint::Program`, looking for
/// opportunities to apply mutations and return them to the caller.
///
/// Ideally, the behaviour of this class (precisely, its `FindMutations` method)
/// should not be probabilistic. This is useful when mutation finders are used
/// for test case reduction, because it enables the test case reducer to
/// systematically explore all available mutations. There may be some
/// exceptions, however. For example, if a huge number of mutations is returned,
/// it would make sense to apply only a probabilistically selected subset of
/// them.
class MutationFinder {
public:
/// Virtual destructor.
virtual ~MutationFinder();
/// @brief Traverses the `program`, looking for opportunities to apply
/// mutations.
///
/// @param program - the program being fuzzed.
/// @param node_id_map - a map from `tint::ast::` nodes in the `program` to
/// their unique ids.
/// @param probability_context - determines various probabilistic stuff in the
/// mutator. This should ideally be used as less as possible.
/// @return all the found mutations.
virtual MutationList FindMutations(
const tint::Program& program,
NodeIdMap* node_id_map,
ProbabilityContext* probability_context) const = 0;
/// @brief Compute a probability of applying a single mutation, returned by
/// this class.
///
/// @param probability_context - contains information about various
/// non-deterministic stuff in the fuzzer.
/// @return a number in the range [0; 100] which is a chance of applying a
/// mutation.
virtual uint32_t GetChanceOfApplyingMutation(
ProbabilityContext* probability_context) const = 0;
};
using MutationFinderList = std::vector<std::unique_ptr<MutationFinder>>;
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_AST_FUZZER_MUTATION_FINDER_H_

View File

@ -1,79 +0,0 @@
// 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 "fuzzers/tint_ast_fuzzer/mutation_finders/replace_identifiers.h"
#include <memory>
#include "fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
#include "fuzzers/tint_ast_fuzzer/util.h"
#include "src/sem/expression.h"
#include "src/sem/statement.h"
#include "src/sem/variable.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
MutationList MutationFinderReplaceIdentifiers::FindMutations(
const tint::Program& program,
NodeIdMap* node_id_map,
ProbabilityContext* probability_context) const {
MutationList result;
// Go through each variable in the AST and for each user of that variable, try
// to replace it with some other variable usage.
for (const auto* node : program.SemNodes().Objects()) {
const auto* sem_variable = tint::As<sem::Variable>(node);
if (!sem_variable) {
continue;
}
// Iterate over all users of `sem_variable`.
for (const auto* user : sem_variable->Users()) {
// Get all variables that can be used to replace the `user` of
// `sem_variable`.
auto candidate_variables = util::GetAllVarsInScope(
program, user->Stmt(), [user](const sem::Variable* var) {
return var != user->Variable() && var->Type() == user->Type();
});
if (candidate_variables.empty()) {
// No suitable replacements have been found.
continue;
}
const auto* replacement =
candidate_variables[probability_context->GetRandomIndex(
candidate_variables)];
result.push_back(std::make_unique<MutationReplaceIdentifier>(
node_id_map->GetId(user->Declaration()),
node_id_map->GetId(replacement->Declaration())));
}
}
return result;
}
uint32_t MutationFinderReplaceIdentifiers::GetChanceOfApplyingMutation(
ProbabilityContext* probability_context) const {
return probability_context->GetChanceOfReplacingIdentifiers();
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,42 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_AST_FUZZER_MUTATION_FINDERS_REPLACE_IDENTIFIERS_H_
#define FUZZERS_TINT_AST_FUZZER_MUTATION_FINDERS_REPLACE_IDENTIFIERS_H_
#include "fuzzers/tint_ast_fuzzer/mutation_finder.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
/// Looks for opportunities to apply `MutationReplaceIdentifier`.
///
/// Concretely, for each variable in the module, tries to replace its users with
/// the uses of some other variables.
class MutationFinderReplaceIdentifiers : public MutationFinder {
public:
MutationList FindMutations(
const tint::Program& program,
NodeIdMap* node_id_map,
ProbabilityContext* probability_context) const override;
uint32_t GetChanceOfApplyingMutation(
ProbabilityContext* probability_context) const override;
};
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_AST_FUZZER_MUTATION_FINDERS_REPLACE_IDENTIFIERS_H_

View File

@ -1,106 +0,0 @@
// 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 "fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
#include <utility>
#include "fuzzers/tint_ast_fuzzer/util.h"
#include "src/program_builder.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
MutationReplaceIdentifier::MutationReplaceIdentifier(
protobufs::MutationReplaceIdentifier message)
: message_(std::move(message)) {}
MutationReplaceIdentifier::MutationReplaceIdentifier(uint32_t use_id,
uint32_t replacement_id) {
message_.set_use_id(use_id);
message_.set_replacement_id(replacement_id);
}
bool MutationReplaceIdentifier::IsApplicable(
const tint::Program& program,
const NodeIdMap& node_id_map) const {
const auto* use_ast_node = tint::As<ast::IdentifierExpression>(
node_id_map.GetNode(message_.use_id()));
if (!use_ast_node) {
// Either the `use_id` is invalid or the node is not an
// `IdentifierExpression`.
return false;
}
const auto* use_sem_node =
tint::As<sem::VariableUser>(program.Sem().Get(use_ast_node));
if (!use_sem_node) {
// Either the semantic information is not present for a `use_node` or that
// node is not a variable user.
return false;
}
const auto* replacement_ast_node =
tint::As<ast::Variable>(node_id_map.GetNode(message_.replacement_id()));
if (!replacement_ast_node) {
// Either the `replacement_id` is invalid or is not an id of a variable.
return false;
}
const auto* replacement_sem_node = program.Sem().Get(replacement_ast_node);
if (!replacement_sem_node) {
return false;
}
if (replacement_sem_node == use_sem_node->Variable()) {
return false;
}
auto in_scope =
util::GetAllVarsInScope(program, use_sem_node->Stmt(),
[replacement_sem_node](const sem::Variable* var) {
return var == replacement_sem_node;
});
if (in_scope.empty()) {
// The replacement variable is not in scope.
return false;
}
return use_sem_node->Type() == replacement_sem_node->Type();
}
void MutationReplaceIdentifier::Apply(const NodeIdMap& node_id_map,
tint::CloneContext* clone_context,
NodeIdMap* new_node_id_map) const {
const auto* use_node = node_id_map.GetNode(message_.use_id());
const auto* replacement_var =
tint::As<ast::Variable>(node_id_map.GetNode(message_.replacement_id()));
auto* cloned_replacement =
clone_context->dst->Expr(clone_context->Clone(use_node->source),
clone_context->Clone(replacement_var->symbol));
clone_context->Replace(use_node, cloned_replacement);
new_node_id_map->Add(cloned_replacement, message_.use_id());
}
protobufs::Mutation MutationReplaceIdentifier::ToMessage() const {
protobufs::Mutation mutation;
*mutation.mutable_replace_identifier() = message_;
return mutation;
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,77 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_AST_FUZZER_MUTATIONS_REPLACE_IDENTIFIER_H_
#define FUZZERS_TINT_AST_FUZZER_MUTATIONS_REPLACE_IDENTIFIER_H_
#include "fuzzers/tint_ast_fuzzer/mutation.h"
#include "src/sem/variable.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
/// @see MutationReplaceIdentifier::Apply
class MutationReplaceIdentifier : public Mutation {
public:
/// @brief Constructs an instance of this mutation from a protobuf message.
/// @param message - protobuf message
explicit MutationReplaceIdentifier(
protobufs::MutationReplaceIdentifier message);
/// @brief Constructor.
/// @param use_id - the id of a variable user.
/// @param replacement_id - the id of a variable to replace the `use_id`.
MutationReplaceIdentifier(uint32_t use_id, uint32_t replacement_id);
/// @copybrief Mutation::IsApplicable
///
/// The mutation is applicable iff:
/// - `use_id` is a valid id of an `ast::IdentifierExpression`, that
/// references a variable.
/// - `replacement_id` is a valid id of an `ast::Variable`.
/// - The identifier expression doesn't reference the variable of a
/// `replacement_id`.
/// - The variable with `replacement_id` is in scope of an identifier
/// expression with `use_id`.
/// - The identifier expression and the variable have the same type.
///
/// @copydetails Mutation::IsApplicable
bool IsApplicable(const tint::Program& program,
const NodeIdMap& node_id_map) const override;
/// @copybrief Mutation::Apply
///
/// Replaces the use of an identifier expression with `use_id` with a newly
/// created identifier expression, that references a variable with
/// `replacement_id`. The newly created identifier expression will have the
/// same id as the old one (i.e. `use_id`).
///
/// @copydetails Mutation::Apply
void Apply(const NodeIdMap& node_id_map,
tint::CloneContext* clone_context,
NodeIdMap* new_node_id_map) const override;
protobufs::Mutation ToMessage() const override;
private:
protobufs::MutationReplaceIdentifier message_;
};
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_AST_FUZZER_MUTATIONS_REPLACE_IDENTIFIER_H_

View File

@ -1,670 +0,0 @@
// 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 <string>
#include "gtest/gtest.h"
#include "fuzzers/tint_ast_fuzzer/mutations/replace_identifier.h"
#include "fuzzers/tint_ast_fuzzer/mutator.h"
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
#include "fuzzers/tint_ast_fuzzer/node_id_map.h"
#include "src/ast/call_statement.h"
#include "src/program_builder.h"
#include "src/reader/wgsl/parser.h"
#include "src/writer/wgsl/generator.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
namespace {
TEST(ReplaceIdentifierTest, NotApplicable_Simple) {
std::string content = R"(
fn main() {
let a = 5;
let c = 6;
let b = a + 5;
let d = vec2<i32>(1, 2);
let e = d.x;
}
)";
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_stmts = program.AST().Functions()[0]->body->statements;
const auto* a_var =
main_fn_stmts[0]->As<ast::VariableDeclStatement>()->variable;
ASSERT_NE(a_var, nullptr);
const auto* b_var =
main_fn_stmts[2]->As<ast::VariableDeclStatement>()->variable;
ASSERT_NE(b_var, nullptr);
const auto* e_var =
main_fn_stmts[4]->As<ast::VariableDeclStatement>()->variable;
ASSERT_NE(e_var, nullptr);
auto a_var_id = node_id_map.GetId(a_var);
ASSERT_NE(a_var_id, 0);
auto b_var_id = node_id_map.GetId(b_var);
ASSERT_NE(b_var_id, 0);
const auto* sum_expr = b_var->constructor->As<ast::BinaryExpression>();
ASSERT_NE(sum_expr, nullptr);
auto a_ident_id = node_id_map.GetId(sum_expr->lhs);
ASSERT_NE(a_ident_id, 0);
auto sum_expr_id = node_id_map.GetId(sum_expr);
ASSERT_NE(sum_expr_id, 0);
auto e_var_id = node_id_map.GetId(e_var);
ASSERT_NE(e_var_id, 0);
auto vec_member_access_id = node_id_map.GetId(
e_var->constructor->As<ast::MemberAccessorExpression>()->member);
ASSERT_NE(vec_member_access_id, 0);
// use_id is invalid.
EXPECT_FALSE(MutationReplaceIdentifier(0, a_var_id)
.IsApplicable(program, node_id_map));
// use_id is not an identifier expression.
EXPECT_FALSE(MutationReplaceIdentifier(sum_expr_id, a_var_id)
.IsApplicable(program, node_id_map));
// use_id is an identifier but not a variable user.
EXPECT_FALSE(MutationReplaceIdentifier(vec_member_access_id, a_var_id)
.IsApplicable(program, node_id_map));
// replacement_id is invalid.
EXPECT_FALSE(MutationReplaceIdentifier(a_ident_id, 0)
.IsApplicable(program, node_id_map));
// replacement_id is not a variable.
EXPECT_FALSE(MutationReplaceIdentifier(a_ident_id, sum_expr_id)
.IsApplicable(program, node_id_map));
// Can't replace a variable with itself.
EXPECT_FALSE(MutationReplaceIdentifier(a_ident_id, a_var_id)
.IsApplicable(program, node_id_map));
// Replacement is not in scope.
EXPECT_FALSE(MutationReplaceIdentifier(a_ident_id, b_var_id)
.IsApplicable(program, node_id_map));
EXPECT_FALSE(MutationReplaceIdentifier(a_ident_id, e_var_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, GlobalVarNotInScope) {
// Can't use the global variable if it's not in scope.
std::string shader = R"(
var<private> a: i32;
fn f() {
a = 3;
}
var<private> b: i32;
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[0]
->As<ast::AssignmentStatement>()
->lhs);
ASSERT_NE(use_id, 0);
auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[1]);
ASSERT_NE(replacement_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, NotApplicable1) {
// Can't replace `a` with `b` since the store type is wrong (the same storage
// class though).
std::string shader = R"(
var<private> a: i32;
var<private> b: u32;
fn f() {
*&a = 4;
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[1]);
ASSERT_NE(replacement_id, 0);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[0]
->As<ast::AssignmentStatement>()
->lhs->As<ast::UnaryOpExpression>()
->expr->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, NotApplicable2) {
// Can't replace `a` with `b` since the store type is wrong (the storage
// class is different though).
std::string shader = R"(
var<private> a: i32;
fn f() {
var b: u32;
*&a = 4;
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto replacement_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[0]
->As<ast::VariableDeclStatement>()
->variable);
ASSERT_NE(replacement_id, 0);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[1]
->As<ast::AssignmentStatement>()
->lhs->As<ast::UnaryOpExpression>()
->expr->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, NotApplicable3) {
// Can't replace `a` with `b` since the latter is not a reference (the store
// type is the same, though).
std::string shader = R"(
var<private> a: i32;
fn f() {
let b = 45;
*&a = 4;
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto replacement_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[0]
->As<ast::VariableDeclStatement>()
->variable);
ASSERT_NE(replacement_id, 0);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[1]
->As<ast::AssignmentStatement>()
->lhs->As<ast::UnaryOpExpression>()
->expr->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, NotApplicable4) {
// Can't replace `a` with `b` since the latter is not a reference (the store
// type is the same, though).
std::string shader = R"(
var<private> a: i32;
fn f(b: i32) {
*&a = 4;
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto replacement_id =
node_id_map.GetId(program.AST().Functions()[0]->params[0]);
ASSERT_NE(replacement_id, 0);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[0]
->As<ast::AssignmentStatement>()
->lhs->As<ast::UnaryOpExpression>()
->expr->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, NotApplicable5) {
// Can't replace `a` with `b` since the latter has a wrong access mode
// (`read` for uniform storage class).
std::string shader = R"(
struct S {
a: i32;
};
var<private> a: S;
@group(1) @binding(1) var<uniform> b: S;
fn f() {
*&a = S(4);
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[1]);
ASSERT_NE(replacement_id, 0);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[0]
->As<ast::AssignmentStatement>()
->lhs->As<ast::UnaryOpExpression>()
->expr->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, NotApplicable6) {
// Can't replace `ptr_b` with `a` since the latter is not a pointer.
std::string shader = R"(
struct S {
a: i32;
};
var<private> a: S;
@group(1) @binding(1) var<uniform> b: S;
fn f() {
let ptr_b = &b;
*&a = *ptr_b;
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[0]);
ASSERT_NE(replacement_id, 0);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[1]
->As<ast::AssignmentStatement>()
->rhs->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, NotApplicable8) {
// Can't replace `ptr_b` with `c` since the latter has a wrong access mode and
// storage class.
std::string shader = R"(
struct S {
a: i32;
};
var<private> a: S;
@group(1) @binding(1) var<uniform> b: S;
@group(1) @binding(2) var<storage, write> c: S;
fn f() {
let ptr_b = &b;
*&a = *ptr_b;
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[2]);
ASSERT_NE(replacement_id, 0);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[1]
->As<ast::AssignmentStatement>()
->rhs->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, NotApplicable9) {
// Can't replace `b` with `e` since the latter is not a reference.
std::string shader = R"(
struct S {
a: i32;
};
var<private> a: S;
let e = 3;
@group(1) @binding(1) var<uniform> b: S;
fn f() {
*&a = *&b;
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[1]);
ASSERT_NE(replacement_id, 0);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[0]
->As<ast::AssignmentStatement>()
->rhs->As<ast::UnaryOpExpression>()
->expr->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, NotApplicable10) {
// Can't replace `b` with `e` since the latter has a wrong access mode.
std::string shader = R"(
struct S {
a: i32;
};
var<private> a: S;
@group(0) @binding(0) var<storage, write> e: S;
@group(1) @binding(1) var<uniform> b: S;
fn f() {
*&a = *&b;
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[1]);
ASSERT_NE(replacement_id, 0);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[0]
->As<ast::AssignmentStatement>()
->rhs->As<ast::UnaryOpExpression>()
->expr->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, Applicable1) {
// Can replace `a` with `b` (same storage class).
std::string shader = R"(
fn f() {
var b : vec2<u32>;
var a = vec2<u32>(34u, 45u);
(*&a)[1] = 3u;
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[2]
->As<ast::AssignmentStatement>()
->lhs->As<ast::IndexAccessorExpression>()
->object->As<ast::UnaryOpExpression>()
->expr->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
auto replacement_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[0]
->As<ast::VariableDeclStatement>()
->variable);
ASSERT_NE(replacement_id, 0);
ASSERT_TRUE(MaybeApplyMutation(
program, MutationReplaceIdentifier(use_id, replacement_id), node_id_map,
&program, &node_id_map, nullptr));
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
writer::wgsl::Options options;
auto result = writer::wgsl::Generate(&program, options);
ASSERT_TRUE(result.success) << result.error;
std::string expected_shader = R"(fn f() {
var b : vec2<u32>;
var a = vec2<u32>(34u, 45u);
(*(&(b)))[1] = 3u;
}
)";
ASSERT_EQ(expected_shader, result.wgsl);
}
TEST(ReplaceIdentifierTest, Applicable2) {
// Can replace `ptr_a` with `b` - the function parameter.
std::string shader = R"(
fn f(b: ptr<function, vec2<u32>>) {
var a = vec2<u32>(34u, 45u);
let ptr_a = &a;
(*ptr_a)[1] = 3u;
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[2]
->As<ast::AssignmentStatement>()
->lhs->As<ast::IndexAccessorExpression>()
->object->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
auto replacement_id =
node_id_map.GetId(program.AST().Functions()[0]->params[0]);
ASSERT_NE(replacement_id, 0);
ASSERT_TRUE(MaybeApplyMutation(
program, MutationReplaceIdentifier(use_id, replacement_id), node_id_map,
&program, &node_id_map, nullptr));
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
writer::wgsl::Options options;
auto result = writer::wgsl::Generate(&program, options);
ASSERT_TRUE(result.success) << result.error;
std::string expected_shader = R"(fn f(b : ptr<function, vec2<u32>>) {
var a = vec2<u32>(34u, 45u);
let ptr_a = &(a);
(*(b))[1] = 3u;
}
)";
ASSERT_EQ(expected_shader, result.wgsl);
}
TEST(ReplaceIdentifierTest, NotApplicable12) {
// Can't replace `a` with `b` (both are references with different storage
// class).
std::string shader = R"(
var<private> b : vec2<u32>;
fn f() {
var a = vec2<u32>(34u, 45u);
(*&a)[1] = 3u;
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto use_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[1]
->As<ast::AssignmentStatement>()
->lhs->As<ast::IndexAccessorExpression>()
->object->As<ast::UnaryOpExpression>()
->expr->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[0]);
ASSERT_NE(replacement_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, NotApplicable13) {
// Can't replace `a` with `b` (both are references with different storage
// class).
std::string shader = R"(
var<private> b : vec2<u32>;
fn f() {
var a = vec2<u32>(34u, 45u);
let c = (*&a)[1];
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto use_id = node_id_map.GetId(
program.AST()
.Functions()[0]
->body->statements[1]
->As<ast::VariableDeclStatement>()
->variable->constructor->As<ast::IndexAccessorExpression>()
->object->As<ast::UnaryOpExpression>()
->expr->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
auto replacement_id = node_id_map.GetId(program.AST().GlobalVariables()[0]);
ASSERT_NE(replacement_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
TEST(ReplaceIdentifierTest, NotApplicable14) {
// Can't replace `ptr_a` with `ptr_b` (both are pointers with different
// storage class).
std::string shader = R"(
var<private> b: vec2<u32>;
fn f() {
var a = vec2<u32>(34u, 45u);
let ptr_a = &a;
let ptr_b = &b;
let c = (*ptr_a)[1];
}
)";
Source::File file("test.wgsl", shader);
auto program = reader::wgsl::Parse(&file);
ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
NodeIdMap node_id_map(program);
auto use_id = node_id_map.GetId(
program.AST()
.Functions()[0]
->body->statements[3]
->As<ast::VariableDeclStatement>()
->variable->constructor->As<ast::IndexAccessorExpression>()
->object->As<ast::UnaryOpExpression>()
->expr);
ASSERT_NE(use_id, 0);
auto replacement_id = node_id_map.GetId(program.AST()
.Functions()[0]
->body->statements[2]
->As<ast::VariableDeclStatement>()
->variable);
ASSERT_NE(replacement_id, 0);
ASSERT_FALSE(MutationReplaceIdentifier(use_id, replacement_id)
.IsApplicable(program, node_id_map));
}
} // namespace
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,184 +0,0 @@
// 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 "fuzzers/tint_ast_fuzzer/mutator.h"
#include <cassert>
#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>
#include "fuzzers/tint_ast_fuzzer/mutation_finders/replace_identifiers.h"
#include "fuzzers/tint_ast_fuzzer/node_id_map.h"
#include "src/program_builder.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
namespace {
template <typename T, typename... Args>
void MaybeAddFinder(bool enable_all_mutations,
ProbabilityContext* probability_context,
MutationFinderList* finders,
Args&&... args) {
if (enable_all_mutations || probability_context->RandomBool()) {
finders->push_back(std::make_unique<T>(std::forward<Args>(args)...));
}
}
MutationFinderList CreateMutationFinders(
ProbabilityContext* probability_context,
bool enable_all_mutations) {
MutationFinderList result;
do {
MaybeAddFinder<MutationFinderReplaceIdentifiers>(
enable_all_mutations, probability_context, &result);
} while (result.empty());
return result;
}
} // namespace
bool MaybeApplyMutation(const tint::Program& program,
const Mutation& mutation,
const NodeIdMap& node_id_map,
tint::Program* out_program,
NodeIdMap* out_node_id_map,
protobufs::MutationSequence* mutation_sequence) {
assert(out_program && "`out_program` may not be a nullptr");
assert(out_node_id_map && "`out_node_id_map` may not be a nullptr");
if (!mutation.IsApplicable(program, node_id_map)) {
return false;
}
// The mutated `program` will be copied into the `mutated` program builder.
tint::ProgramBuilder mutated;
tint::CloneContext clone_context(&mutated, &program);
NodeIdMap new_node_id_map;
clone_context.ReplaceAll(
[&node_id_map, &new_node_id_map, &clone_context](const ast::Node* node) {
// Make sure all `tint::ast::` nodes' ids are preserved.
auto* cloned = tint::As<ast::Node>(node->Clone(&clone_context));
new_node_id_map.Add(cloned, node_id_map.GetId(node));
return cloned;
});
mutation.Apply(node_id_map, &clone_context, &new_node_id_map);
if (mutation_sequence) {
*mutation_sequence->add_mutation() = mutation.ToMessage();
}
clone_context.Clone();
*out_program = tint::Program(std::move(mutated));
*out_node_id_map = std::move(new_node_id_map);
return true;
}
tint::Program Replay(tint::Program program,
const protobufs::MutationSequence& mutation_sequence) {
assert(program.IsValid() && "Initial program is invalid");
NodeIdMap node_id_map(program);
for (const auto& mutation_message : mutation_sequence.mutation()) {
auto mutation = Mutation::FromMessage(mutation_message);
auto status = MaybeApplyMutation(program, *mutation, node_id_map, &program,
&node_id_map, nullptr);
(void)status; // `status` will be unused in release mode.
assert(status && "`mutation` is inapplicable - it's most likely a bug");
if (!program.IsValid()) {
// `mutation` has a bug.
break;
}
}
return program;
}
tint::Program Mutate(tint::Program program,
ProbabilityContext* probability_context,
bool enable_all_mutations,
uint32_t max_applied_mutations,
protobufs::MutationSequence* mutation_sequence) {
assert(max_applied_mutations != 0 &&
"Maximum number of mutations is invalid");
assert(program.IsValid() && "Initial program is invalid");
// The number of allowed failed attempts to apply mutations. If this number is
// exceeded, the mutator is considered stuck and the mutation session is
// stopped.
const uint32_t kMaxFailureToApply = 10;
auto finders =
CreateMutationFinders(probability_context, enable_all_mutations);
NodeIdMap node_id_map(program);
// Total number of applied mutations during this call to `Mutate`.
uint32_t applied_mutations = 0;
// The number of consecutively failed attempts to apply mutations.
uint32_t failure_to_apply = 0;
// Apply mutations as long as the `program` is valid, the limit on the number
// of mutations is not reached and the mutator is not stuck (i.e. unable to
// apply any mutations for some time).
while (program.IsValid() && applied_mutations < max_applied_mutations &&
failure_to_apply < kMaxFailureToApply) {
// Get all applicable mutations from some mutation finder.
const auto& mutation_finder =
finders[probability_context->GetRandomIndex(finders)];
auto mutations = mutation_finder->FindMutations(program, &node_id_map,
probability_context);
const auto old_applied_mutations = applied_mutations;
for (const auto& mutation : mutations) {
if (!probability_context->ChoosePercentage(
mutation_finder->GetChanceOfApplyingMutation(
probability_context))) {
// Skip this `mutation` probabilistically.
continue;
}
if (!MaybeApplyMutation(program, *mutation, node_id_map, &program,
&node_id_map, mutation_sequence)) {
// This `mutation` is inapplicable. This may happen if some of the
// earlier mutations cancelled this one.
continue;
}
applied_mutations++;
if (!program.IsValid()) {
// This `mutation` has a bug.
return program;
}
}
if (old_applied_mutations == applied_mutations) {
// No mutation was applied. Increase the counter to prevent an infinite
// loop.
failure_to_apply++;
} else {
failure_to_apply = 0;
}
}
return program;
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,101 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_AST_FUZZER_MUTATOR_H_
#define FUZZERS_TINT_AST_FUZZER_MUTATOR_H_
#include "fuzzers/tint_ast_fuzzer/mutation.h"
#include "fuzzers/tint_ast_fuzzer/mutation_finder.h"
#include "fuzzers/tint_ast_fuzzer/node_id_map.h"
#include "fuzzers/tint_ast_fuzzer/probability_context.h"
#include "fuzzers/tint_ast_fuzzer/protobufs/tint_ast_fuzzer.h"
#include "src/program.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
/// @file
/// @brief Tries to apply a `mutation` to the `program`.
///
/// If the `mutation` is inapplicable, this function will return `false` and
/// `out_program`, `out_node_id_map` and `mutation_sequence` won't be modified.
///
/// The `mutation` is required to produce a valid program when the
/// `Mutation::Apply` method is called. This guarantees that this function
/// returns a valid program as well.
///
/// @param program - the initial program (must be valid).
/// @param mutation - the mutation that will be applied.
/// @param node_id_map - a map from `tint::ast::` nodes in the `program` to
/// their unique ids.
/// @param out_program - the resulting mutated program will be written through
/// this pointer. It may *not* be a `nullptr`. It _may_ point to `program`,
/// so that a program can be updated in place.
/// @param out_node_id_map - will contain new ids for the AST nodes in the
/// mutated program. It may *not* be a `nullptr`. It _may_ point to
/// `node_id_map`, so that a map can be updated in place.
/// @param mutation_sequence - the message about this mutation will be recorded
/// here. It may be a `nullptr`, in which case it's ignored.
/// @return `true` if the `mutation` was applied.
/// @return `false` if the `mutation` is inapplicable.
bool MaybeApplyMutation(const tint::Program& program,
const Mutation& mutation,
const NodeIdMap& node_id_map,
tint::Program* out_program,
NodeIdMap* out_node_id_map,
protobufs::MutationSequence* mutation_sequence);
/// @brief Applies mutations from `mutations_sequence` to the `program`.
///
/// All mutations in `mutation_sequence` must be applicable. Additionally, all
/// mutations must produce a valid program when the `Mutation::Apply` method is
/// called. This guarantees that this function returns a valid program as well.
///
/// @param program - the initial program - must be valid.
/// @param mutation_sequence - a sequence of mutations.
/// @return the mutated program.
tint::Program Replay(tint::Program program,
const protobufs::MutationSequence& mutation_sequence);
/// @brief Applies up to `max_applied_mutations` mutations to the `program`.
///
/// All applied mutations must produce valid programs. This guarantees that the
/// returned program is valid as well. The returned program may be identical to
/// the initial `program` if no mutation was applied.
///
/// @param program - initial program - must be valid.
/// @param probability_context - contains information about various
/// probabilistic behaviour of the fuzzer.
/// @param enable_all_mutations - if `false`, only mutations from a
/// probabilistically selected set of mutation types are applied. If `true`,
/// all mutation types are considered.
/// @param max_applied_mutations - the maximum number of applied mutations. This
/// may not be 0.
/// @param mutation_sequence - applied mutations will be recorded into this
/// protobuf message. This argument may be `nullptr`, in which case it's
/// ignored.
/// @return the mutated program.
tint::Program Mutate(tint::Program program,
ProbabilityContext* probability_context,
bool enable_all_mutations,
uint32_t max_applied_mutations,
protobufs::MutationSequence* mutation_sequence);
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_AST_FUZZER_MUTATOR_H_

View File

@ -1,65 +0,0 @@
// 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 "fuzzers/tint_ast_fuzzer/node_id_map.h"
#include <cassert>
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
NodeIdMap::NodeIdMap() = default;
NodeIdMap::NodeIdMap(const Program& program) : NodeIdMap() {
for (const auto* node : program.ASTNodes().Objects()) {
Add(node, TakeFreshId());
}
}
NodeIdMap::IdType NodeIdMap::GetId(const ast::Node* node) const {
auto it = node_to_id_.find(node);
return it == node_to_id_.end() ? 0 : it->second;
}
const ast::Node* NodeIdMap::GetNode(IdType id) const {
auto it = id_to_node_.find(id);
return it == id_to_node_.end() ? nullptr : it->second;
}
void NodeIdMap::Add(const ast::Node* node, IdType id) {
assert(!node_to_id_.count(node) && "The node already exists in the map");
assert(IdIsFreshAndValid(id) && "Id already exists in the map or Id is zero");
assert(node && "`node` can't be a nullptr");
node_to_id_[node] = id;
id_to_node_[id] = node;
if (id >= fresh_id_) {
fresh_id_ = id + 1;
}
}
bool NodeIdMap::IdIsFreshAndValid(IdType id) {
return id && !id_to_node_.count(id);
}
NodeIdMap::IdType NodeIdMap::TakeFreshId() {
assert(fresh_id_ != 0 && "`NodeIdMap` id has overflowed");
return fresh_id_++;
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,96 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_AST_FUZZER_NODE_ID_MAP_H_
#define FUZZERS_TINT_AST_FUZZER_NODE_ID_MAP_H_
#include <unordered_map>
#include "src/program.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
/// Contains a one-to-one mapping between the nodes in the AST of the program
/// and their ids.
///
/// The motivation for having this mapping is:
/// - To be able to uniquely identify a node in the AST. This will be used
/// to record transformations in the protobuf messages.
/// - When the AST is being modified, only the mapping for the modified nodes
/// must be affected. That is, if some node is unchanged, it must have the
/// same id defined in this class.
///
/// This class achieves these goals partially. Concretely, the only way to
/// change the AST is by cloning it since all instances of `tint::ast::` classes
/// are immutable. This will invalidate all the pointers to the AST nodes which
/// are used in this class. To overcome this, a new instance of this class is
/// created with all the cloned nodes and the old instance is discarded.
class NodeIdMap {
public:
/// Type of the id used by this map.
using IdType = uint32_t;
/// Creates an empty map.
NodeIdMap();
/// @brief Initializes this instance with all the nodes in the `program`.
/// @param program - must be valid.
explicit NodeIdMap(const Program& program);
/// @brief Returns a node for the given `id`.
/// @param id - any value is accepted.
/// @return a pointer to some node if `id` exists in this map.
/// @return `nullptr` otherwise.
const ast::Node* GetNode(IdType id) const;
/// @brief Returns an id of the given `node`.
/// @param node - can be a `nullptr`.
/// @return not equal to 0 if `node` exists in this map.
/// @return 0 otherwise.
IdType GetId(const ast::Node* node) const;
/// @brief Adds a mapping from `node` to `id` to this map.
/// @param node - may not be a `nullptr` and can't be present in this map.
/// @param id - may not be 0 and can't be present in this map.
void Add(const ast::Node* node, IdType id);
/// @brief Returns whether the id is fresh by checking if it exists in
/// the id map and the id is not 0.
/// @param id - an id that is used to check in the map.
/// @return true the given id is fresh and valid (non-zero).
/// @return false otherwise.
bool IdIsFreshAndValid(IdType id);
/// @brief Returns an id that is guaranteed to be unoccupied in this map.
///
/// This will effectively increase the counter. This means that two
/// consecutive calls to this method will return different ids.
///
/// @return an unoccupied id.
IdType TakeFreshId();
private:
IdType fresh_id_ = 1;
std::unordered_map<const ast::Node*, IdType> node_to_id_;
std::unordered_map<IdType, const ast::Node*> id_to_node_;
};
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_AST_FUZZER_NODE_ID_MAP_H_

View File

@ -1,36 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_AST_FUZZER_OVERRIDE_CLI_PARAMS_H_
#define FUZZERS_TINT_AST_FUZZER_OVERRIDE_CLI_PARAMS_H_
#include "fuzzers/tint_ast_fuzzer/cli.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
/// @brief Allows CLI parameters to be overridden.
///
/// This function allows fuzz targets to override particular CLI parameters,
/// for example forcing a particular back-end to be targeted.
///
/// @param cli_params - the parsed CLI parameters to be updated.
void OverrideCliParams(CliParams& cli_params);
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_AST_FUZZER_OVERRIDE_CLI_PARAMS_H_

View File

@ -1,44 +0,0 @@
// 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 "fuzzers/tint_ast_fuzzer/probability_context.h"
#include <cassert>
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
namespace {
const std::pair<uint32_t, uint32_t> kChanceOfReplacingIdentifiers = {30, 70};
} // namespace
ProbabilityContext::ProbabilityContext(RandomGenerator* generator)
: generator_(generator),
chance_of_replacing_identifiers_(
RandomFromRange(kChanceOfReplacingIdentifiers)) {
assert(generator != nullptr && "generator must not be nullptr");
}
uint32_t ProbabilityContext::RandomFromRange(
std::pair<uint32_t, uint32_t> range) {
assert(range.first <= range.second && "Range must be non-decreasing");
return generator_->GetUInt32(
range.first, range.second + 1); // + 1 need since range is inclusive.
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,77 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_AST_FUZZER_PROBABILITY_CONTEXT_H_
#define FUZZERS_TINT_AST_FUZZER_PROBABILITY_CONTEXT_H_
#include <utility>
#include <vector>
#include "fuzzers/random_generator.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
/// This class is intended to be used by the `MutationFinder`s to introduce some
/// variance to the mutation process.
class ProbabilityContext {
public:
/// Initializes this instance with a random number generator.
/// @param generator - must not be a `nullptr`. Must remain in scope as long
/// as this
/// instance exists.
explicit ProbabilityContext(RandomGenerator* generator);
/// Get random bool with even odds
/// @returns true 50% of the time and false %50 of time.
bool RandomBool() { return generator_->GetBool(); }
/// Get random bool with weighted odds
/// @param percentage - likelihood of true being returned
/// @returns true |percentage|% of the time, and false (100 - |percentage|)%
/// of the time.
bool ChoosePercentage(uint32_t percentage) {
return generator_->GetWeightedBool(percentage);
}
/// Returns a random value in the range `[0; arr.size())`.
/// @tparam T - type of the elements in the vector.
/// @param arr - may not be empty.
/// @return the random index in the `arr`.
template <typename T>
size_t GetRandomIndex(const std::vector<T>& arr) {
return static_cast<size_t>(generator_->GetUInt64(arr.size()));
}
/// @return the probability of replacing some identifier with some other one.
uint32_t GetChanceOfReplacingIdentifiers() const {
return chance_of_replacing_identifiers_;
}
private:
/// @param range - a pair of integers `a` and `b` s.t. `a <= b`.
/// @return an random number in the range `[a; b]`.
uint32_t RandomFromRange(std::pair<uint32_t, uint32_t> range);
RandomGenerator* generator_;
uint32_t chance_of_replacing_identifiers_;
};
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_AST_FUZZER_PROBABILITY_CONTEXT_H_

View File

@ -1,35 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_AST_FUZZER_PROTOBUFS_TINT_AST_FUZZER_H_
#define FUZZERS_TINT_AST_FUZZER_PROTOBUFS_TINT_AST_FUZZER_H_
// Compilation of the protobuf library and its autogenerated code can produce
// warnings. Ignore them since we can't control them.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#pragma clang diagnostic ignored "-Wsign-conversion"
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#pragma clang diagnostic ignored "-Wextra-semi-stmt"
#pragma clang diagnostic ignored "-Winconsistent-missing-destructor-override"
#pragma clang diagnostic ignored "-Wweak-vtables"
#pragma clang diagnostic ignored "-Wsuggest-destructor-override"
#pragma clang diagnostic ignored "-Wreserved-identifier"
#include "fuzzers/tint_ast_fuzzer/protobufs/tint_ast_fuzzer.pb.h"
#pragma clang diagnostic pop
#endif // FUZZERS_TINT_AST_FUZZER_PROTOBUFS_TINT_AST_FUZZER_H_

View File

@ -1,48 +0,0 @@
// 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.
syntax = "proto3";
package tint.fuzzers.ast_fuzzer.protobufs;
message Mutation {
oneof mutation { MutationReplaceIdentifier replace_identifier = 1; };
}
message MutationSequence {
repeated Mutation mutation = 1;
}
message MutatorState {
// Contains the state of the fuzzer.
// The program that is being fuzzed. This can be either
// the original program (if mutation sequence is available) or
// the mutated version (if mutations are being recorded).
string program = 1;
// The sequence of mutations that was applied to the `program`.
// This may not have any mutations if they are not being recorded.
MutationSequence mutation_sequence = 2;
}
message MutationReplaceIdentifier {
// This transformation replaces a use of one variable with another.
// The id of the use of a variable in the AST.
uint32 use_id = 1;
// The id of a definition of a variable to replace the use with.
uint32 replacement_id = 2;
}

View File

@ -1,28 +0,0 @@
// 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 "fuzzers/tint_ast_fuzzer/cli.h"
#include "fuzzers/tint_ast_fuzzer/override_cli_params.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
void OverrideCliParams(CliParams& /*unused*/) {
// Leave the CLI parameters unchanged.
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,33 +0,0 @@
// 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 <cassert>
#include "fuzzers/tint_ast_fuzzer/cli.h"
#include "fuzzers/tint_ast_fuzzer/override_cli_params.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
void OverrideCliParams(CliParams& cli_params) {
assert(cli_params.fuzzing_target == FuzzingTarget::kAll &&
"The fuzzing target should not have been set by a CLI parameter: it "
"should have its default value.");
cli_params.fuzzing_target = FuzzingTarget::kHlsl;
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,33 +0,0 @@
// 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 <cassert>
#include "fuzzers/tint_ast_fuzzer/cli.h"
#include "fuzzers/tint_ast_fuzzer/override_cli_params.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
void OverrideCliParams(CliParams& cli_params) {
assert(cli_params.fuzzing_target == FuzzingTarget::kAll &&
"The fuzzing target should not have been set by a CLI parameter: it "
"should have its default value.");
cli_params.fuzzing_target = FuzzingTarget::kMsl;
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,33 +0,0 @@
// 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 <cassert>
#include "fuzzers/tint_ast_fuzzer/cli.h"
#include "fuzzers/tint_ast_fuzzer/override_cli_params.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
void OverrideCliParams(CliParams& cli_params) {
assert(cli_params.fuzzing_target == FuzzingTarget::kAll &&
"The fuzzing target should not have been set by a CLI parameter: it "
"should have its default value.");
cli_params.fuzzing_target = FuzzingTarget::kSpv;
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,33 +0,0 @@
// 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 <cassert>
#include "fuzzers/tint_ast_fuzzer/cli.h"
#include "fuzzers/tint_ast_fuzzer/override_cli_params.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
void OverrideCliParams(CliParams& cli_params) {
assert(cli_params.fuzzing_target == FuzzingTarget::kAll &&
"The fuzzing target should not have been set by a CLI parameter: it "
"should have its default value.");
cli_params.fuzzing_target = FuzzingTarget::kWgsl;
}
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,109 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_AST_FUZZER_UTIL_H_
#define FUZZERS_TINT_AST_FUZZER_UTIL_H_
#include <vector>
#include "src/ast/module.h"
#include "src/ast/variable_decl_statement.h"
#include "src/castable.h"
#include "src/program.h"
#include "src/sem/block_statement.h"
#include "src/sem/function.h"
#include "src/sem/statement.h"
#include "src/sem/variable.h"
namespace tint {
namespace fuzzers {
namespace ast_fuzzer {
namespace util {
/// @file
/// @brief Returns all in-scope variables (including formal function parameters)
/// related to statement `curr_stmt`.
///
/// These variables are additionally filtered by applying a predicate `pred`.
///
/// @tparam Pred - a predicate that accepts a `const sem::Variable*` and returns
/// `bool`.
/// @param program - the program to look for variables in.
/// @param curr_stmt - the current statement. Everything below it is not in
/// scope.
/// @param pred - a predicate (e.g. a function pointer, functor, lambda etc) of
/// type `Pred`.
/// @return a vector of all variables that can be accessed from `curr_stmt`.
template <typename Pred>
std::vector<const sem::Variable*> GetAllVarsInScope(
const tint::Program& program,
const sem::Statement* curr_stmt,
Pred&& pred) {
std::vector<const sem::Variable*> result;
// Walk up the hierarchy of blocks in which `curr_stmt` is contained.
for (const auto* block = curr_stmt->Block(); block;
block = tint::As<sem::BlockStatement>(block->Parent())) {
for (const auto* stmt : block->Declaration()->statements) {
if (stmt == curr_stmt->Declaration()) {
// `curr_stmt` was found. This is only possible if `block is the
// enclosing block of `curr_stmt` since the AST nodes are not shared.
// Because of all this, skip the iteration of the inner loop since
// the rest of the instructions in the `block` are not visible from the
// `curr_stmt`.
break;
}
if (const auto* var_node = tint::As<ast::VariableDeclStatement>(stmt)) {
const auto* sem_var = program.Sem().Get(var_node->variable);
if (pred(sem_var)) {
result.push_back(sem_var);
}
}
}
}
// Process function parameters.
for (const auto* param : curr_stmt->Function()->Parameters()) {
if (pred(param)) {
result.push_back(param);
}
}
// Global variables do not belong to any ast::BlockStatement.
for (const auto* global_decl : program.AST().GlobalDeclarations()) {
if (global_decl == curr_stmt->Function()->Declaration()) {
// The same situation as in the previous loop. The current function has
// been reached. If there are any variables declared below, they won't be
// visible in this function. Thus, exit the loop.
break;
}
if (const auto* global_var = tint::As<ast::Variable>(global_decl)) {
const auto* sem_node = program.Sem().Get(global_var);
if (pred(sem_node)) {
result.push_back(sem_node);
}
}
}
return result;
}
} // namespace util
} // namespace ast_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_AST_FUZZER_UTIL_H_

View File

@ -1,35 +0,0 @@
// 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 "fuzzers/fuzzer_init.h"
#include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/transform_builder.h"
namespace tint {
namespace fuzzers {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
TransformBuilder tb(data, size);
tb.AddTransform<transform::BindingRemapper>();
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
fuzzer.SetDumpInput(GetCliParams().dump_input);
fuzzer.SetEnforceValidity(GetCliParams().enforce_validity);
return fuzzer.Run(data, size);
}
} // namespace fuzzers
} // namespace tint

View File

@ -1,157 +0,0 @@
// 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 <cassert>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include "fuzzers/tint_common_fuzzer.h"
namespace {
/// Controls the target language in which code will be generated.
enum class TargetLanguage {
kHlsl,
kMsl,
kSpv,
kWgsl,
kTargetLanguageMax,
};
/// Copies the content from the file named `input_file` to `buffer`,
/// assuming each element in the file is of type `T`. If any error occurs,
/// writes error messages to the standard error stream and returns false.
/// Assumes the size of a `T` object is divisible by its required alignment.
/// @returns true if we successfully read the file.
template <typename T>
bool ReadFile(const std::string& input_file, std::vector<T>* buffer) {
if (!buffer) {
std::cerr << "The buffer pointer was null" << std::endl;
return false;
}
FILE* file = nullptr;
#if defined(_MSC_VER)
fopen_s(&file, input_file.c_str(), "rb");
#else
file = fopen(input_file.c_str(), "rb");
#endif
if (!file) {
std::cerr << "Failed to open " << input_file << std::endl;
return false;
}
fseek(file, 0, SEEK_END);
const auto file_size = static_cast<size_t>(ftell(file));
if (0 != (file_size % sizeof(T))) {
std::cerr << "File " << input_file
<< " does not contain an integral number of objects: "
<< file_size << " bytes in the file, require " << sizeof(T)
<< " bytes per object" << std::endl;
fclose(file);
return false;
}
fseek(file, 0, SEEK_SET);
buffer->clear();
buffer->resize(file_size / sizeof(T));
size_t bytes_read = fread(buffer->data(), 1, file_size, file);
fclose(file);
if (bytes_read != file_size) {
std::cerr << "Failed to read " << input_file << std::endl;
return false;
}
return true;
}
} // namespace
int main(int argc, const char** argv) {
if (argc < 2 || argc > 3) {
std::cerr << "Usage: " << argv[0] << " <input file> [hlsl|msl|spv|wgsl]"
<< std::endl;
return 1;
}
std::string input_filename(argv[1]);
std::vector<uint8_t> data;
if (!ReadFile<uint8_t>(input_filename, &data)) {
return 1;
}
if (data.empty()) {
return 0;
}
tint::fuzzers::DataBuilder builder(data.data(), data.size());
TargetLanguage target_language;
if (argc == 3) {
std::string target_language_string = argv[2];
if (target_language_string == "hlsl") {
target_language = TargetLanguage::kHlsl;
} else if (target_language_string == "msl") {
target_language = TargetLanguage::kMsl;
} else if (target_language_string == "spv") {
target_language = TargetLanguage::kSpv;
} else {
assert(target_language_string == "wgsl" && "Unknown target language.");
target_language = TargetLanguage::kWgsl;
}
} else {
target_language = builder.enum_class<TargetLanguage>(
static_cast<uint32_t>(TargetLanguage::kTargetLanguageMax));
}
switch (target_language) {
case TargetLanguage::kHlsl: {
tint::fuzzers::CommonFuzzer fuzzer(tint::fuzzers::InputFormat::kWGSL,
tint::fuzzers::OutputFormat::kHLSL);
return fuzzer.Run(data.data(), data.size());
}
case TargetLanguage::kMsl: {
tint::writer::msl::Options options;
GenerateMslOptions(&builder, &options);
tint::fuzzers::CommonFuzzer fuzzer(tint::fuzzers::InputFormat::kWGSL,
tint::fuzzers::OutputFormat::kMSL);
fuzzer.SetOptionsMsl(options);
return fuzzer.Run(data.data(), data.size());
}
case TargetLanguage::kSpv: {
tint::writer::spirv::Options options;
GenerateSpirvOptions(&builder, &options);
tint::fuzzers::CommonFuzzer fuzzer(tint::fuzzers::InputFormat::kWGSL,
tint::fuzzers::OutputFormat::kSpv);
fuzzer.SetOptionsSpirv(options);
return fuzzer.Run(data.data(), data.size());
}
case TargetLanguage::kWgsl: {
tint::fuzzers::CommonFuzzer fuzzer(tint::fuzzers::InputFormat::kWGSL,
tint::fuzzers::OutputFormat::kWGSL);
return fuzzer.Run(data.data(), data.size());
}
default:
std::cerr << "Aborting due to unknown target language; fuzzer must be "
"misconfigured."
<< std::endl;
abort();
}
}

View File

@ -1,353 +0,0 @@
// 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 "fuzzers/tint_common_fuzzer.h"
#include <cassert>
#include <cstring>
#include <fstream>
#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#if TINT_BUILD_SPV_READER
#include "spirv-tools/libspirv.hpp"
#endif // TINT_BUILD_SPV_READER
#include "src/ast/module.h"
#include "src/diagnostic/formatter.h"
#include "src/program.h"
#include "src/utils/hash.h"
namespace tint {
namespace fuzzers {
namespace {
// A macro is used to avoid FATAL_ERROR creating its own stack frame. This leads
// to better de-duplication of bug reports, because ClusterFuzz only uses the
// top few stack frames for de-duplication, and a FATAL_ERROR stack frame
// provides no useful information.
#define FATAL_ERROR(diags, msg_string) \
do { \
std::string msg = msg_string; \
auto printer = tint::diag::Printer::create(stderr, true); \
if (!msg.empty()) { \
printer->write(msg + "\n", {diag::Color::kRed, true}); \
} \
tint::diag::Formatter().format(diags, printer.get()); \
__builtin_trap(); \
} while (false)
[[noreturn]] void TintInternalCompilerErrorReporter(
const tint::diag::List& diagnostics) {
FATAL_ERROR(diagnostics, "");
}
// Wrapping in a macro, so it can be a one-liner in the code, but not
// introduce another level in the stack trace. This will help with de-duping
// ClusterFuzz issues.
#define CHECK_INSPECTOR(program, inspector) \
do { \
if ((inspector).has_error()) { \
if (!enforce_validity) { \
return; \
} \
FATAL_ERROR((program)->Diagnostics(), \
"Inspector failed: " + (inspector).error()); \
} \
} while (false)
// Wrapping in a macro to make code more readable and help with issue de-duping.
#define VALIDITY_ERROR(diags, msg_string) \
do { \
if (!enforce_validity) { \
return 0; \
} \
FATAL_ERROR(diags, msg_string); \
} while (false)
bool SPIRVToolsValidationCheck(const tint::Program& program,
const std::vector<uint32_t>& spirv) {
spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1);
const tint::diag::List& diags = program.Diagnostics();
tools.SetMessageConsumer([diags](spv_message_level_t, const char*,
const spv_position_t& pos, const char* msg) {
std::stringstream out;
out << "Unexpected spirv-val error:\n"
<< (pos.line + 1) << ":" << (pos.column + 1) << ": " << msg
<< std::endl;
auto printer = tint::diag::Printer::create(stderr, true);
printer->write(out.str(), {diag::Color::kYellow, false});
tint::diag::Formatter().format(diags, printer.get());
});
return tools.Validate(spirv.data(), spirv.size(),
spvtools::ValidatorOptions());
}
} // namespace
void GenerateSpirvOptions(DataBuilder* b, writer::spirv::Options* options) {
*options = b->build<writer::spirv::Options>();
}
void GenerateWgslOptions(DataBuilder* b, writer::wgsl::Options* options) {
*options = b->build<writer::wgsl::Options>();
}
void GenerateHlslOptions(DataBuilder* b, writer::hlsl::Options* options) {
*options = b->build<writer::hlsl::Options>();
}
void GenerateMslOptions(DataBuilder* b, writer::msl::Options* options) {
*options = b->build<writer::msl::Options>();
}
CommonFuzzer::CommonFuzzer(InputFormat input, OutputFormat output)
: input_(input), output_(output) {}
CommonFuzzer::~CommonFuzzer() = default;
int CommonFuzzer::Run(const uint8_t* data, size_t size) {
tint::SetInternalCompilerErrorReporter(&TintInternalCompilerErrorReporter);
#if TINT_BUILD_WGSL_WRITER
tint::Program::printer = [](const tint::Program* program) {
auto result = tint::writer::wgsl::Generate(program, {});
if (!result.error.empty()) {
return "error: " + result.error;
}
return result.wgsl;
};
#endif // TINT_BUILD_WGSL_WRITER
Program program;
#if TINT_BUILD_SPV_READER
std::vector<uint32_t> spirv_input(size / sizeof(uint32_t));
#endif // TINT_BUILD_SPV_READER
#if TINT_BUILD_WGSL_READER || TINT_BUILD_SPV_READER
auto dump_input_data = [&](auto& content, const char* extension) {
size_t hash = utils::Hash(content);
auto filename = "fuzzer_input_" + std::to_string(hash) + extension; //
std::ofstream fout(filename, std::ios::binary);
fout.write(reinterpret_cast<const char*>(data),
static_cast<std::streamsize>(size));
std::cout << "Dumped input data to " << filename << std::endl;
};
#endif
switch (input_) {
#if TINT_BUILD_WGSL_READER
case InputFormat::kWGSL: {
// Clear any existing diagnostics, as these will hold pointers to file_,
// which we are about to release.
diagnostics_ = {};
std::string str(reinterpret_cast<const char*>(data), size);
file_ = std::make_unique<Source::File>("test.wgsl", str);
if (dump_input_) {
dump_input_data(str, ".wgsl");
}
program = reader::wgsl::Parse(file_.get());
break;
}
#endif // TINT_BUILD_WGSL_READER
#if TINT_BUILD_SPV_READER
case InputFormat::kSpv: {
// `spirv_input` has been initialized with the capacity to store `size /
// sizeof(uint32_t)` uint32_t values. If `size` is not a multiple of
// sizeof(uint32_t) then not all of `data` can be copied into
// `spirv_input`, and any trailing bytes are discarded.
std::memcpy(spirv_input.data(), data,
spirv_input.size() * sizeof(uint32_t));
if (spirv_input.empty()) {
return 0;
}
if (dump_input_) {
dump_input_data(spirv_input, ".spv");
}
program = reader::spirv::Parse(spirv_input);
break;
}
#endif // TINT_BUILD_SPV_READER
}
if (!program.IsValid()) {
diagnostics_ = program.Diagnostics();
return 0;
}
#if TINT_BUILD_SPV_READER
if (input_ == InputFormat::kSpv &&
!SPIRVToolsValidationCheck(program, spirv_input)) {
FATAL_ERROR(
program.Diagnostics(),
"Fuzzing detected invalid input spirv not being caught by Tint");
}
#endif // TINT_BUILD_SPV_READER
RunInspector(&program);
diagnostics_ = program.Diagnostics();
if (transform_manager_) {
auto out = transform_manager_->Run(&program, *transform_inputs_);
if (!out.program.IsValid()) {
// Transforms can produce error messages for bad input.
// Catch ICEs and errors from non transform systems.
for (const auto& diag : out.program.Diagnostics()) {
if (diag.severity > diag::Severity::Error ||
diag.system != diag::System::Transform) {
VALIDITY_ERROR(program.Diagnostics(),
"Fuzzing detected valid input program being "
"transformed into an invalid output program");
}
}
}
program = std::move(out.program);
RunInspector(&program);
}
switch (output_) {
case OutputFormat::kWGSL: {
#if TINT_BUILD_WGSL_WRITER
auto result = writer::wgsl::Generate(&program, options_wgsl_);
generated_wgsl_ = std::move(result.wgsl);
if (!result.success) {
VALIDITY_ERROR(
program.Diagnostics(),
"WGSL writer errored on validated input:\n" + result.error);
}
#endif // TINT_BUILD_WGSL_WRITER
break;
}
case OutputFormat::kSpv: {
#if TINT_BUILD_SPV_WRITER
auto result = writer::spirv::Generate(&program, options_spirv_);
generated_spirv_ = std::move(result.spirv);
if (!result.success) {
VALIDITY_ERROR(
program.Diagnostics(),
"SPIR-V writer errored on validated input:\n" + result.error);
}
if (!SPIRVToolsValidationCheck(program, generated_spirv_)) {
VALIDITY_ERROR(program.Diagnostics(),
"Fuzzing detected invalid spirv being emitted by Tint");
}
#endif // TINT_BUILD_SPV_WRITER
break;
}
case OutputFormat::kHLSL: {
#if TINT_BUILD_HLSL_WRITER
auto result = writer::hlsl::Generate(&program, options_hlsl_);
generated_hlsl_ = std::move(result.hlsl);
if (!result.success) {
VALIDITY_ERROR(
program.Diagnostics(),
"HLSL writer errored on validated input:\n" + result.error);
}
#endif // TINT_BUILD_HLSL_WRITER
break;
}
case OutputFormat::kMSL: {
#if TINT_BUILD_MSL_WRITER
auto result = writer::msl::Generate(&program, options_msl_);
generated_msl_ = std::move(result.msl);
if (!result.success) {
VALIDITY_ERROR(
program.Diagnostics(),
"MSL writer errored on validated input:\n" + result.error);
}
#endif // TINT_BUILD_MSL_WRITER
break;
}
}
return 0;
}
void CommonFuzzer::RunInspector(Program* program) {
inspector::Inspector inspector(program);
diagnostics_ = program->Diagnostics();
auto entry_points = inspector.GetEntryPoints();
CHECK_INSPECTOR(program, inspector);
auto constant_ids = inspector.GetConstantIDs();
CHECK_INSPECTOR(program, inspector);
auto constant_name_to_id = inspector.GetConstantNameToIdMap();
CHECK_INSPECTOR(program, inspector);
for (auto& ep : entry_points) {
inspector.GetRemappedNameForEntryPoint(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetStorageSize(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetUniformBufferResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetStorageBufferResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetReadOnlyStorageBufferResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetSamplerResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetComparisonSamplerResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetSampledTextureResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetMultisampledTextureResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetWriteOnlyStorageTextureResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetDepthTextureResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetDepthMultisampledTextureResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetExternalTextureResourceBindings(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetSamplerTextureUses(ep.name);
CHECK_INSPECTOR(program, inspector);
inspector.GetWorkgroupStorageSize(ep.name);
CHECK_INSPECTOR(program, inspector);
}
}
} // namespace fuzzers
} // namespace tint

View File

@ -1,119 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_COMMON_FUZZER_H_
#define FUZZERS_TINT_COMMON_FUZZER_H_
#include <cassert>
#include <cstring>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "include/tint/tint.h"
#include "fuzzers/data_builder.h"
namespace tint {
namespace fuzzers {
void GenerateSpirvOptions(DataBuilder* b, writer::spirv::Options* options);
void GenerateWgslOptions(DataBuilder* b, writer::wgsl::Options* options);
void GenerateHlslOptions(DataBuilder* b, writer::hlsl::Options* options);
void GenerateMslOptions(DataBuilder* b, writer::msl::Options* options);
enum class InputFormat { kWGSL, kSpv };
enum class OutputFormat { kWGSL, kSpv, kHLSL, kMSL };
class CommonFuzzer {
public:
explicit CommonFuzzer(InputFormat input, OutputFormat output);
~CommonFuzzer();
void SetTransformManager(transform::Manager* tm, transform::DataMap* inputs) {
assert((!tm || inputs) && "DataMap must be !nullptr if Manager !nullptr");
transform_manager_ = tm;
transform_inputs_ = inputs;
}
void SetDumpInput(bool enabled) { dump_input_ = enabled; }
void SetEnforceValidity(bool enabled) { enforce_validity = enabled; }
int Run(const uint8_t* data, size_t size);
const tint::diag::List& Diagnostics() const { return diagnostics_; }
bool HasErrors() const { return diagnostics_.contains_errors(); }
const std::vector<uint32_t>& GetGeneratedSpirv() const {
return generated_spirv_;
}
const std::string& GetGeneratedWgsl() const { return generated_wgsl_; }
const std::string& GetGeneratedHlsl() const { return generated_hlsl_; }
const std::string& GetGeneratedMsl() const { return generated_msl_; }
void SetOptionsSpirv(const writer::spirv::Options& options) {
options_spirv_ = options;
}
void SetOptionsWgsl(const writer::wgsl::Options& options) {
options_wgsl_ = options;
}
void SetOptionsHlsl(const writer::hlsl::Options& options) {
options_hlsl_ = options;
}
void SetOptionsMsl(const writer::msl::Options& options) {
options_msl_ = options;
}
private:
InputFormat input_;
OutputFormat output_;
transform::Manager* transform_manager_ = nullptr;
transform::DataMap* transform_inputs_ = nullptr;
bool dump_input_ = false;
tint::diag::List diagnostics_;
bool enforce_validity = false;
std::vector<uint32_t> generated_spirv_;
std::string generated_wgsl_;
std::string generated_hlsl_;
std::string generated_msl_;
writer::spirv::Options options_spirv_;
writer::wgsl::Options options_wgsl_;
writer::hlsl::Options options_hlsl_;
writer::msl::Options options_msl_;
#if TINT_BUILD_WGSL_READER
/// The source file needs to live at least as long as #diagnostics_
std::unique_ptr<Source::File> file_;
#endif // TINT_BUILD_WGSL_READER
// Run series of reflection operations to exercise the Inspector API.
void RunInspector(Program* program);
};
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_COMMON_FUZZER_H_

View File

@ -1,35 +0,0 @@
// 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 "fuzzers/fuzzer_init.h"
#include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/transform_builder.h"
namespace tint {
namespace fuzzers {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
TransformBuilder tb(data, size);
tb.AddTransform<transform::FirstIndexOffset>();
fuzzers::CommonFuzzer fuzzer(InputFormat::kWGSL, OutputFormat::kWGSL);
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
fuzzer.SetDumpInput(GetCliParams().dump_input);
fuzzer.SetEnforceValidity(GetCliParams().enforce_validity);
return fuzzer.Run(data, size);
}
} // namespace fuzzers
} // namespace tint

View File

@ -1,55 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_READER_WRITER_FUZZER_H_
#define FUZZERS_TINT_READER_WRITER_FUZZER_H_
#include <memory>
#include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/transform_builder.h"
namespace tint {
namespace fuzzers {
class ReaderWriterFuzzer : public CommonFuzzer {
public:
explicit ReaderWriterFuzzer(InputFormat input, OutputFormat output)
: CommonFuzzer(input, output) {}
~ReaderWriterFuzzer() {}
void SetTransformManager(transform::Manager* tm, transform::DataMap* inputs) {
tm_set_ = true;
CommonFuzzer::SetTransformManager(tm, inputs);
}
int Run(const uint8_t* data, size_t size) {
if (!tm_set_) {
tb_ = std::make_unique<TransformBuilder>(data, size);
tb_->AddTransform<tint::transform::Robustness>();
SetTransformManager(tb_->manager(), tb_->data_map());
}
return CommonFuzzer::Run(data, size);
}
private:
bool tm_set_ = false;
std::unique_ptr<TransformBuilder> tb_;
};
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_READER_WRITER_FUZZER_H_

View File

@ -1,75 +0,0 @@
# 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.
function(add_tint_regex_fuzzer NAME)
add_executable(${NAME} ${NAME}.cc ${REGEX_FUZZER_SOURCES})
target_link_libraries(${NAME} libtint-fuzz libtint_regex_fuzzer)
tint_default_compile_options(${NAME})
target_compile_definitions(${NAME} PRIVATE CUSTOM_MUTATOR)
target_include_directories(${NAME} PRIVATE ${CMAKE_BINARY_DIR})
endfunction()
set(LIBTINT_REGEX_FUZZER_SOURCES
../mersenne_twister_engine.cc
../mersenne_twister_engine.h
../random_generator.cc
../random_generator.h
../random_generator_engine.cc
../random_generator_engine.h
wgsl_mutator.cc
wgsl_mutator.h)
# Add static library target.
add_library(libtint_regex_fuzzer STATIC ${LIBTINT_REGEX_FUZZER_SOURCES})
tint_default_compile_options(libtint_regex_fuzzer)
set(REGEX_FUZZER_SOURCES
cli.cc
cli.h
fuzzer.cc
override_cli_params.h
../tint_common_fuzzer.cc
../tint_common_fuzzer.h)
set_source_files_properties(fuzzer.cc PROPERTIES COMPILE_FLAGS -Wno-missing-prototypes)
# Add libfuzzer targets.
# Targets back-ends according to command line arguments.
add_tint_regex_fuzzer(tint_regex_fuzzer)
# Targets back-ends individually.
add_tint_regex_fuzzer(tint_regex_hlsl_writer_fuzzer)
add_tint_regex_fuzzer(tint_regex_msl_writer_fuzzer)
add_tint_regex_fuzzer(tint_regex_spv_writer_fuzzer)
add_tint_regex_fuzzer(tint_regex_wgsl_writer_fuzzer)
# Add tests.
if (${TINT_BUILD_TESTS})
set(TEST_SOURCES
regex_fuzzer_tests.cc)
add_executable(tint_regex_fuzzer_unittests ${TEST_SOURCES})
target_include_directories(
tint_regex_fuzzer_unittests PRIVATE ${gmock_SOURCE_DIR}/include)
target_link_libraries(tint_regex_fuzzer_unittests gmock_main libtint_regex_fuzzer)
tint_default_compile_options(tint_regex_fuzzer_unittests)
target_compile_options(tint_regex_fuzzer_unittests PRIVATE
-Wno-global-constructors
-Wno-weak-vtables
-Wno-covered-switch-default)
target_include_directories(tint_regex_fuzzer_unittests PRIVATE ${CMAKE_BINARY_DIR})
add_test(NAME tint_regex_fuzzer_unittests COMMAND tint_regex_fuzzer_unittests)
endif ()

View File

@ -1,126 +0,0 @@
// 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 "fuzzers/tint_regex_fuzzer/cli.h"
#include <cstring>
#include <iostream>
#include <limits>
#include <sstream>
#include <string>
#include <utility>
namespace tint {
namespace fuzzers {
namespace regex_fuzzer {
namespace {
const char* const kHelpMessage = R"(
This is a fuzzer for the Tint compiler that works by mutating a WGSL shader.
Below is a list of all supported parameters for this fuzzer. You may want to
run it with -help=1 to check out libfuzzer parameters.
-tint_fuzzing_target=
Specifies the shading language to target during fuzzing.
This must be one or a combination of `wgsl`, `spv`, `hlsl`,
`msl` (without `) separated by commas. By default it's
`wgsl,msl,hlsl,spv`.
-tint_help
Show this message. Note that there is also a -help=1
parameter that will display libfuzzer's help message.
)";
bool HasPrefix(const char* str, const char* prefix) {
return strncmp(str, prefix, strlen(prefix)) == 0;
}
[[noreturn]] void InvalidParam(const char* param) {
std::cout << "Invalid value for " << param << std::endl;
std::cout << kHelpMessage << std::endl;
exit(1);
}
bool ParseFuzzingTarget(const char* value, FuzzingTarget* out) {
if (!strcmp(value, "wgsl")) {
*out = FuzzingTarget::kWgsl;
} else if (!strcmp(value, "spv")) {
*out = FuzzingTarget::kSpv;
} else if (!strcmp(value, "msl")) {
*out = FuzzingTarget::kMsl;
} else if (!strcmp(value, "hlsl")) {
*out = FuzzingTarget::kHlsl;
} else {
return false;
}
return true;
}
} // namespace
CliParams ParseCliParams(int* argc, char** argv) {
CliParams cli_params;
auto help = false;
for (int i = *argc - 1; i > 0; --i) {
auto param = argv[i];
auto recognized_parameter = true;
if (HasPrefix(param, "-tint_fuzzing_target=")) {
auto result = FuzzingTarget::kNone;
std::stringstream ss(param + sizeof("-tint_fuzzing_target=") - 1);
for (std::string value; std::getline(ss, value, ',');) {
auto tmp = FuzzingTarget::kNone;
if (!ParseFuzzingTarget(value.c_str(), &tmp)) {
InvalidParam(param);
}
result = result | tmp;
}
if (result == FuzzingTarget::kNone) {
InvalidParam(param);
}
cli_params.fuzzing_target = result;
} else if (!strcmp(param, "-tint_help")) {
help = true;
} else {
recognized_parameter = false;
}
if (recognized_parameter) {
// Remove the recognized parameter from the list of all parameters by
// swapping it with the last one. This will suppress warnings in the
// libFuzzer about unrecognized parameters. By default, libFuzzer thinks
// that all user-defined parameters start with two dashes. However, we are
// forced to use a single one to make the fuzzer compatible with the
// ClusterFuzz.
std::swap(argv[i], argv[*argc - 1]);
*argc -= 1;
}
}
if (help) {
std::cout << kHelpMessage << std::endl;
exit(0);
}
return cli_params;
}
} // namespace regex_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,64 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_REGEX_FUZZER_CLI_H_
#define FUZZERS_TINT_REGEX_FUZZER_CLI_H_
#include <cstdint>
namespace tint {
namespace fuzzers {
namespace regex_fuzzer {
/// The backend this fuzzer will test.
enum class FuzzingTarget {
kNone = 0,
kHlsl = 1 << 0,
kMsl = 1 << 1,
kSpv = 1 << 2,
kWgsl = 1 << 3,
kAll = kHlsl | kMsl | kSpv | kWgsl
};
inline FuzzingTarget operator|(FuzzingTarget a, FuzzingTarget b) {
return static_cast<FuzzingTarget>(static_cast<int>(a) | static_cast<int>(b));
}
inline FuzzingTarget operator&(FuzzingTarget a, FuzzingTarget b) {
return static_cast<FuzzingTarget>(static_cast<int>(a) & static_cast<int>(b));
}
/// CLI parameters accepted by the fuzzer. Type -tint_help in the CLI to see the
/// help message
struct CliParams {
/// Compiler backends we want to fuzz.
FuzzingTarget fuzzing_target = FuzzingTarget::kAll;
};
/// @brief Parses CLI parameters.
///
/// This function will exit the process with non-zero return code if some
/// parameters are invalid. This function will remove recognized parameters from
/// `argv` and adjust `argc` accordingly.
///
/// @param argc - the total number of parameters.
/// @param argv - array of all CLI parameters.
/// @return parsed parameters.
CliParams ParseCliParams(int* argc, char** argv);
} // namespace regex_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_REGEX_FUZZER_CLI_H_

View File

@ -1,156 +0,0 @@
// 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 <cassert>
#include <cstddef>
#include <cstdint>
#include "fuzzers/random_generator.h"
#include "fuzzers/tint_common_fuzzer.h"
#include "fuzzers/tint_regex_fuzzer/cli.h"
#include "fuzzers/tint_regex_fuzzer/override_cli_params.h"
#include "fuzzers/tint_regex_fuzzer/wgsl_mutator.h"
#include "fuzzers/transform_builder.h"
#include "src/reader/wgsl/parser.h"
#include "src/writer/wgsl/generator.h"
namespace tint {
namespace fuzzers {
namespace regex_fuzzer {
namespace {
CliParams cli_params{};
enum class MutationKind {
kSwapIntervals,
kDeleteInterval,
kDuplicateInterval,
kReplaceIdentifier,
kReplaceLiteral,
kInsertReturnStatement,
kNumMutationKinds
};
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
// Parse CLI parameters. `ParseCliParams` will call `exit` if some parameter
// is invalid.
cli_params = ParseCliParams(argc, *argv);
// For some fuzz targets it is desirable to force the values of certain CLI
// parameters after parsing.
OverrideCliParams(cli_params);
return 0;
}
extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* data,
size_t size,
size_t max_size,
unsigned seed) {
std::string wgsl_code(data, data + size);
const std::vector<std::string> delimiters{";"};
RandomGenerator generator(seed);
std::string delimiter =
delimiters[generator.GetUInt32(static_cast<uint32_t>(delimiters.size()))];
MutationKind mutation_kind = static_cast<MutationKind>(generator.GetUInt32(
static_cast<uint32_t>(MutationKind::kNumMutationKinds)));
switch (mutation_kind) {
case MutationKind::kSwapIntervals:
if (!SwapRandomIntervals(delimiter, wgsl_code, generator)) {
return 0;
}
break;
case MutationKind::kDeleteInterval:
if (!DeleteRandomInterval(delimiter, wgsl_code, generator)) {
return 0;
}
break;
case MutationKind::kDuplicateInterval:
if (!DuplicateRandomInterval(delimiter, wgsl_code, generator)) {
return 0;
}
break;
case MutationKind::kReplaceIdentifier:
if (!ReplaceRandomIdentifier(wgsl_code, generator)) {
return 0;
}
break;
case MutationKind::kReplaceLiteral:
if (!ReplaceRandomIntLiteral(wgsl_code, generator)) {
return 0;
}
break;
case MutationKind::kInsertReturnStatement:
if (!InsertReturnStatement(wgsl_code, generator)) {
return 0;
}
break;
default:
assert(false && "Unreachable");
return 0;
}
if (wgsl_code.size() > max_size) {
return 0;
}
memcpy(data, wgsl_code.c_str(), wgsl_code.size());
return wgsl_code.size();
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size == 0) {
return 0;
}
struct Target {
FuzzingTarget fuzzing_target;
OutputFormat output_format;
const char* name;
};
Target targets[] = {{FuzzingTarget::kWgsl, OutputFormat::kWGSL, "WGSL"},
{FuzzingTarget::kHlsl, OutputFormat::kHLSL, "HLSL"},
{FuzzingTarget::kMsl, OutputFormat::kMSL, "MSL"},
{FuzzingTarget::kSpv, OutputFormat::kSpv, "SPV"}};
for (auto target : targets) {
if ((target.fuzzing_target & cli_params.fuzzing_target) !=
target.fuzzing_target) {
continue;
}
TransformBuilder tb(data, size);
tb.AddTransform<tint::transform::Robustness>();
CommonFuzzer fuzzer(InputFormat::kWGSL, target.output_format);
fuzzer.SetTransformManager(tb.manager(), tb.data_map());
fuzzer.Run(data, size);
}
return 0;
}
} // namespace
} // namespace regex_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,36 +0,0 @@
// 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.
#ifndef FUZZERS_TINT_REGEX_FUZZER_OVERRIDE_CLI_PARAMS_H_
#define FUZZERS_TINT_REGEX_FUZZER_OVERRIDE_CLI_PARAMS_H_
#include "fuzzers/tint_regex_fuzzer/cli.h"
namespace tint {
namespace fuzzers {
namespace regex_fuzzer {
/// @brief Allows CLI parameters to be overridden.
///
/// This function allows fuzz targets to override particular CLI parameters,
/// for example forcing a particular back-end to be targeted.
///
/// @param cli_params - the parsed CLI parameters to be updated.
void OverrideCliParams(CliParams& cli_params);
} // namespace regex_fuzzer
} // namespace fuzzers
} // namespace tint
#endif // FUZZERS_TINT_REGEX_FUZZER_OVERRIDE_CLI_PARAMS_H_

View File

@ -1,521 +0,0 @@
// 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 <string>
#include "gtest/gtest.h"
#include "fuzzers/tint_regex_fuzzer/wgsl_mutator.h"
namespace tint {
namespace fuzzers {
namespace regex_fuzzer {
namespace {
// Swaps two non-consecutive regions in the edge
TEST(SwapRegionsTest, SwapIntervalsEdgeNonConsecutive) {
std::string R1 = ";region1;", R2 = ";regionregion2;",
R3 = ";regionregionregion3;";
std::string all_regions = R1 + R2 + R3;
// this call should swap R1 with R3.
SwapIntervals(0, R1.length(), R1.length() + R2.length(), R3.length(),
all_regions);
ASSERT_EQ(R3 + R2 + R1, all_regions);
}
// Swaps two non-consecutive regions not in the edge
TEST(SwapRegionsTest, SwapIntervalsNonConsecutiveNonEdge) {
std::string R1 = ";region1;", R2 = ";regionregion2;",
R3 = ";regionregionregion3;", R4 = ";regionregionregionregion4;",
R5 = ";regionregionregionregionregion5;";
std::string all_regions = R1 + R2 + R3 + R4 + R5;
// this call should swap R2 with R4.
SwapIntervals(R1.length(), R2.length(),
R1.length() + R2.length() + R3.length(), R4.length(),
all_regions);
ASSERT_EQ(R1 + R4 + R3 + R2 + R5, all_regions);
}
// Swaps two consecutive regions not in the edge (sorrounded by other
// regions)
TEST(SwapRegionsTest, SwapIntervalsConsecutiveEdge) {
std::string R1 = ";region1;", R2 = ";regionregion2;",
R3 = ";regionregionregion3;", R4 = ";regionregionregionregion4;",
R5 = ";regionregionregionregionregion5;";
std::string all_regions = R1 + R2 + R3 + R4;
// this call should swap R2 with R3.
SwapIntervals(R1.length(), R2.length(), R1.length() + R2.length(),
R3.length(), all_regions);
ASSERT_EQ(R1 + R3 + R2 + R4, all_regions);
}
// Swaps two consecutive regions not in the edge (not sorrounded by other
// regions)
TEST(SwapRegionsTest, SwapIntervalsConsecutiveNonEdge) {
std::string R1 = ";region1;", R2 = ";regionregion2;",
R3 = ";regionregionregion3;", R4 = ";regionregionregionregion4;",
R5 = ";regionregionregionregionregion5;";
std::string all_regions = R1 + R2 + R3 + R4 + R5;
// this call should swap R4 with R5.
SwapIntervals(R1.length() + R2.length() + R3.length(), R4.length(),
R1.length() + R2.length() + R3.length() + R4.length(),
R5.length(), all_regions);
ASSERT_EQ(R1 + R2 + R3 + R5 + R4, all_regions);
}
// Deletes the first region.
TEST(DeleteRegionTest, DeleteFirstRegion) {
std::string R1 = ";region1;", R2 = ";regionregion2;",
R3 = ";regionregionregion3;", R4 = ";regionregionregionregion4;",
R5 = ";regionregionregionregionregion5;";
std::string all_regions = R1 + R2 + R3 + R4 + R5;
// This call should delete R1.
DeleteInterval(0, R1.length(), all_regions);
ASSERT_EQ(";" + R2 + R3 + R4 + R5, all_regions);
}
// Deletes the last region.
TEST(DeleteRegionTest, DeleteLastRegion) {
std::string R1 = ";region1;", R2 = ";regionregion2;",
R3 = ";regionregionregion3;", R4 = ";regionregionregionregion4;",
R5 = ";regionregionregionregionregion5;";
std::string all_regions = R1 + R2 + R3 + R4 + R5;
// This call should delete R5.
DeleteInterval(R1.length() + R2.length() + R3.length() + R4.length(),
R5.length(), all_regions);
ASSERT_EQ(R1 + R2 + R3 + R4 + ";", all_regions);
}
// Deletes the middle region.
TEST(DeleteRegionTest, DeleteMiddleRegion) {
std::string R1 = ";region1;", R2 = ";regionregion2;",
R3 = ";regionregionregion3;", R4 = ";regionregionregionregion4;",
R5 = ";regionregionregionregionregion5;";
std::string all_regions = R1 + R2 + R3 + R4 + R5;
// This call should delete R3.
DeleteInterval(R1.length() + R2.length(), R3.length(), all_regions);
ASSERT_EQ(R1 + R2 + ";" + R4 + R5, all_regions);
}
TEST(InsertRegionTest, InsertRegionTest1) {
std::string R1 = ";region1;", R2 = ";regionregion2;",
R3 = ";regionregionregion3;", R4 = ";regionregionregionregion4;",
R5 = ";regionregionregionregionregion5;";
std::string all_regions = R1 + R2 + R3 + R4 + R5;
// This call should insert R2 after R4.
DuplicateInterval(R1.length(), R2.length(),
R1.length() + R2.length() + R3.length() + R4.length() - 1,
all_regions);
ASSERT_EQ(R1 + R2 + R3 + R4 + R2.substr(1, R2.size() - 1) + R5, all_regions);
}
TEST(InsertRegionTest, InsertRegionTest2) {
std::string R1 = ";region1;", R2 = ";regionregion2;",
R3 = ";regionregionregion3;", R4 = ";regionregionregionregion4;",
R5 = ";regionregionregionregionregion5;";
std::string all_regions = R1 + R2 + R3 + R4 + R5;
// This call should insert R3 after R1.
DuplicateInterval(R1.length() + R2.length(), R3.length(), R1.length() - 1,
all_regions);
ASSERT_EQ(R1 + R3.substr(1, R3.length() - 1) + R2 + R3 + R4 + R5,
all_regions);
}
TEST(InsertRegionTest, InsertRegionTest3) {
std::string R1 = ";region1;", R2 = ";regionregion2;",
R3 = ";regionregionregion3;", R4 = ";regionregionregionregion4;",
R5 = ";regionregionregionregionregion5;";
std::string all_regions = R1 + R2 + R3 + R4 + R5;
// This call should insert R2 after R5.
DuplicateInterval(R1.length(), R2.length(), all_regions.length() - 1,
all_regions);
ASSERT_EQ(R1 + R2 + R3 + R4 + R5 + R2.substr(1, R2.length() - 1),
all_regions);
}
TEST(ReplaceIdentifierTest, ReplaceIdentifierTest1) {
std::string R1 = "|region1|", R2 = "; region2;",
R3 = "---------region3---------", R4 = "++region4++",
R5 = "***region5***";
std::string all_regions = R1 + R2 + R3 + R4 + R5;
// Replaces R3 with R1.
ReplaceRegion(0, R1.length(), R1.length() + R2.length(), R3.length(),
all_regions);
ASSERT_EQ(R1 + R2 + R1 + R4 + R5, all_regions);
}
TEST(ReplaceIdentifierTest, ReplaceIdentifierTest2) {
std::string R1 = "|region1|", R2 = "; region2;",
R3 = "---------region3---------", R4 = "++region4++",
R5 = "***region5***";
std::string all_regions = R1 + R2 + R3 + R4 + R5;
// Replaces R5 with R3.
ReplaceRegion(R1.length() + R2.length(), R3.length(),
R1.length() + R2.length() + R3.length() + R4.length(),
R5.length(), all_regions);
ASSERT_EQ(R1 + R2 + R3 + R4 + R3, all_regions);
}
TEST(GetIdentifierTest, GetIdentifierTest1) {
std::string wgsl_code =
R"(fn clamp_0acf8f() {
var res: vec2<f32> = clamp(vec2<f32>(), vec2<f32>(), vec2<f32>());
}
@stage(vertex)
fn vertex_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f();"
return vec4<f32>();
}
@stage(fragment)
fn fragment_main() {
clamp_0acf8f();
}
@stage(compute) @workgroup_size(1)
fn compute_main() {"
var<private> foo: f32 = 0.0;
clamp_0acf8f();
})";
std::vector<std::pair<size_t, size_t>> identifiers_pos =
GetIdentifiers(wgsl_code);
std::vector<std::pair<size_t, size_t>> ground_truth = {
std::make_pair(3, 12), std::make_pair(28, 3), std::make_pair(37, 4),
std::make_pair(49, 5), std::make_pair(60, 3), std::make_pair(68, 4),
std::make_pair(81, 4), std::make_pair(110, 5), std::make_pair(130, 2),
std::make_pair(140, 4), std::make_pair(151, 7), std::make_pair(169, 4),
std::make_pair(190, 12), std::make_pair(216, 6), std::make_pair(228, 3),
std::make_pair(251, 5), std::make_pair(273, 2), std::make_pair(285, 4),
std::make_pair(302, 12), std::make_pair(333, 5), std::make_pair(349, 14),
std::make_pair(373, 2), std::make_pair(384, 4), std::make_pair(402, 3),
std::make_pair(415, 3), std::make_pair(420, 3), std::make_pair(439, 12)};
ASSERT_EQ(ground_truth, identifiers_pos);
}
TEST(TestGetLiteralsValues, TestGetLiteralsValues1) {
std::string wgsl_code =
R"(fn clamp_0acf8f() {
var res: vec2<f32> = clamp(vec2<f32>(), vec2<f32>(), vec2<f32>());
}
@stage(vertex)
fn vertex_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f();
var foo_1: i32 = 3;
return vec4<f32>();
}
@stage(fragment)
fn fragment_main() {
clamp_0acf8f();
}
@stage(compute) @workgroup_size(1)
fn compute_main() {
var<private> foo: f32 = 0.0;
var foo_2: i32 = 10;
clamp_0acf8f();
}
foo_1 = 5 + 7;
var foo_3 : i32 = -20;)";
std::vector<std::pair<size_t, size_t>> literals_pos =
GetIntLiterals(wgsl_code);
std::vector<std::string> ground_truth = {"3", "10", "5", "7", "-20"};
std::vector<std::string> result;
for (auto pos : literals_pos) {
result.push_back(wgsl_code.substr(pos.first, pos.second));
}
ASSERT_EQ(ground_truth, result);
}
TEST(InsertReturnTest, FindClosingBrace) {
std::string wgsl_code =
R"(fn clamp_0acf8f() {
if(false){
} else{
var res: vec2<f32> = clamp(vec2<f32>(), vec2<f32>(), vec2<f32>());
}
}
@stage(vertex)
fn vertex_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f();
var foo_1: i32 = 3;
return vec4<f32>();
}
@stage(fragment)
fn fragment_main() {
clamp_0acf8f();
}
@stage(compute) @workgroup_size(1)
fn compute_main() {
var<private> foo: f32 = 0.0;
var foo_2: i32 = 10;
clamp_0acf8f();
}
foo_1 = 5 + 7;
var foo_3 : i32 = -20;
)";
size_t opening_bracket_pos = 18;
size_t closing_bracket_pos = FindClosingBrace(opening_bracket_pos, wgsl_code);
// The -1 is needed since the function body starts after the left bracket.
std::string function_body = wgsl_code.substr(
opening_bracket_pos + 1, closing_bracket_pos - opening_bracket_pos - 1);
std::string expected =
R"(
if(false){
} else{
var res: vec2<f32> = clamp(vec2<f32>(), vec2<f32>(), vec2<f32>());
}
)";
ASSERT_EQ(expected, function_body);
}
TEST(InsertReturnTest, FindClosingBraceFailing) {
std::string wgsl_code =
R"(fn clamp_0acf8f() {
// This comment } causes the test to fail.
"if(false){
} else{
var res: vec2<f32> = clamp(vec2<f32>(), vec2<f32>(), vec2<f32>());
}
}
@stage(vertex)
fn vertex_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f();
var foo_1: i32 = 3;
return vec4<f32>();
}
@stage(fragment)
fn fragment_main() {
clamp_0acf8f();
}
@stage(compute) @workgroup_size(1)
fn compute_main() {
var<private> foo: f32 = 0.0;
var foo_2: i32 = 10;
clamp_0acf8f();
}
foo_1 = 5 + 7;
var foo_3 : i32 = -20;)";
size_t opening_bracket_pos = 18;
size_t closing_bracket_pos = FindClosingBrace(opening_bracket_pos, wgsl_code);
// The -1 is needed since the function body starts after the left bracket.
std::string function_body = wgsl_code.substr(
opening_bracket_pos + 1, closing_bracket_pos - opening_bracket_pos - 1);
std::string expected =
R"(// This comment } causes the test to fail.
"if(false){
} else{
var res: vec2<f32> = clamp(vec2<f32>(), vec2<f32>(), vec2<f32>());
})";
ASSERT_NE(expected, function_body);
}
TEST(TestInsertReturn, TestInsertReturn1) {
std::string wgsl_code =
R"(fn clamp_0acf8f() {
var res: vec2<f32> = clamp(vec2<f32>(), vec2<f32>(), vec2<f32>());
}
@stage(vertex)
fn vertex_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f();
var foo_1: i32 = 3;
return vec4<f32>();
}
@stage(fragment)
fn fragment_main() {
clamp_0acf8f();
}
@stage(compute) @workgroup_size(1)
fn compute_main() {
var<private> foo: f32 = 0.0;
var foo_2: i32 = 10;
clamp_0acf8f();
}
foo_1 = 5 + 7;
var foo_3 : i32 = -20;)";
std::vector<size_t> semicolon_pos;
for (size_t pos = wgsl_code.find(";", 0); pos != std::string::npos;
pos = wgsl_code.find(";", pos + 1)) {
semicolon_pos.push_back(pos);
}
// should insert a return true statement after the first semicolon of the
// first function the the WGSL-like string above.
wgsl_code.insert(semicolon_pos[0] + 1, "return true;");
std::string expected_wgsl_code =
R"(fn clamp_0acf8f() {
var res: vec2<f32> = clamp(vec2<f32>(), vec2<f32>(), vec2<f32>());return true;
}
@stage(vertex)
fn vertex_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f();
var foo_1: i32 = 3;
return vec4<f32>();
}
@stage(fragment)
fn fragment_main() {
clamp_0acf8f();
}
@stage(compute) @workgroup_size(1)
fn compute_main() {
var<private> foo: f32 = 0.0;
var foo_2: i32 = 10;
clamp_0acf8f();
}
foo_1 = 5 + 7;
var foo_3 : i32 = -20;)";
ASSERT_EQ(expected_wgsl_code, wgsl_code);
}
TEST(TestInsertReturn, TestFunctionPositions) {
std::string wgsl_code =
R"(fn clamp_0acf8f() {
var res: vec2<f32> = clamp(vec2<f32>(), vec2<f32>(), vec2<f32>());
}
@stage(vertex)
fn vertex_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f();
var foo_1: i32 = 3;
return vec4<f32>();
}
@stage(fragment)
fn fragment_main() {
clamp_0acf8f();
}
@stage(compute) @workgroup_size(1)
fn compute_main() {
var<private> foo: f32 = 0.0;
var foo_2: i32 = 10;
clamp_0acf8f();
}
fn vert_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f();
var foo_1: i32 = 3;
return vec4<f32>();
}
foo_1 = 5 + 7;
var foo_3 : i32 = -20;)";
std::vector<size_t> function_positions = GetFunctionBodyPositions(wgsl_code);
std::vector<size_t> expected_positions = {187, 607};
ASSERT_EQ(expected_positions, function_positions);
}
TEST(TestInsertReturn, TestMissingSemicolon) {
std::string wgsl_code =
R"(fn clamp_0acf8f() {
var res: vec2<f32> = clamp(vec2<f32>(), vec2<f32>(), vec2<f32>())
}
@stage(vertex)
fn vertex_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f()
var foo_1: i32 = 3
return vec4<f32>()
}
@stage(fragment)
fn fragment_main() {
clamp_0acf8f();
}
@stage(compute) @workgroup_size(1)
fn compute_main() {
var<private> foo: f32 = 0.0;
var foo_2: i32 = 10;
clamp_0acf8f();
}
fn vert_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f()
var foo_1: i32 = 3
return vec4<f32>()
}
foo_1 = 5 + 7;
var foo_3 : i32 = -20;)";
RandomGenerator generator(0);
InsertReturnStatement(wgsl_code, generator);
// No semicolons found in the function's body, so wgsl_code
// should remain unchanged.
std::string expected_wgsl_code =
R"(fn clamp_0acf8f() {
var res: vec2<f32> = clamp(vec2<f32>(), vec2<f32>(), vec2<f32>())
}
@stage(vertex)
fn vertex_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f()
var foo_1: i32 = 3
return vec4<f32>()
}
@stage(fragment)
fn fragment_main() {
clamp_0acf8f();
}
@stage(compute) @workgroup_size(1)
fn compute_main() {
var<private> foo: f32 = 0.0;
var foo_2: i32 = 10;
clamp_0acf8f();
}
fn vert_main() -> @builtin(position) vec4<f32> {
clamp_0acf8f()
var foo_1: i32 = 3
return vec4<f32>()
}
foo_1 = 5 + 7;
var foo_3 : i32 = -20;)";
ASSERT_EQ(expected_wgsl_code, wgsl_code);
}
} // namespace
} // namespace regex_fuzzer
} // namespace fuzzers
} // namespace tint

View File

@ -1,28 +0,0 @@
// 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 "fuzzers/tint_regex_fuzzer/cli.h"
#include "fuzzers/tint_regex_fuzzer/override_cli_params.h"
namespace tint {
namespace fuzzers {
namespace regex_fuzzer {
void OverrideCliParams(CliParams& /*unused*/) {
// Leave the CLI parameters unchanged.
}
} // namespace regex_fuzzer
} // namespace fuzzers
} // namespace tint

Some files were not shown because too many files have changed in this diff Show More