blob: 0f1cc863904b555d48135fcbe18d6803075dc7e8 [file] [log] [blame]
// Copyright 2023 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/tint/fuzzers/apply_substitute_overrides.h"
#include "src/tint/lang/wgsl/reader/lower/lower.h"
#include "src/tint/lang/wgsl/reader/parser/parser.h"
#include "src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.h"
#include "src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.h"
#include "src/tint/lang/wgsl/writer/raise/raise.h"
#include "src/tint/lang/wgsl/writer/writer.h"
[[noreturn]] void TintInternalCompilerErrorReporter(const tint::InternalCompilerError& err) {
std::cerr << err.Error() << std::endl;
__builtin_trap();
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::string str(reinterpret_cast<const char*>(data), size);
tint::SetInternalCompilerErrorReporter(&TintInternalCompilerErrorReporter);
tint::Source::File file("test.wgsl", str);
// Parse the wgsl, create the src program
tint::wgsl::reader::Parser parser(&file);
parser.set_max_errors(1);
if (!parser.Parse()) {
return 0;
}
auto src = parser.program();
if (!src.IsValid()) {
return 0;
}
auto is_unsupported = [](const tint::ast::Enable* enable) {
for (auto ext : enable->extensions) {
switch (ext->name) {
case tint::wgsl::Extension::kChromiumExperimentalDp4A:
case tint::wgsl::Extension::kChromiumExperimentalFullPtrParameters:
case tint::wgsl::Extension::kChromiumExperimentalPixelLocal:
case tint::wgsl::Extension::kChromiumExperimentalPushConstant:
case tint::wgsl::Extension::kChromiumInternalDualSourceBlending:
case tint::wgsl::Extension::kChromiumInternalRelaxedUniformLayout:
return true;
default:
break;
}
}
return false;
};
if (src.AST().Enables().Any(is_unsupported)) {
return 0;
}
src = tint::fuzzers::ApplySubstituteOverrides(std::move(src));
if (!src.IsValid()) {
return 0;
}
auto ir = tint::wgsl::reader::ProgramToIR(src);
if (!ir) {
std::cerr << ir.Failure() << std::endl;
__builtin_trap();
}
if (auto res = tint::wgsl::reader::Lower(ir.Get()); !res) {
std::cerr << res.Failure() << std::endl;
__builtin_trap();
}
if (auto res = tint::wgsl::writer::Raise(ir.Get()); !res) {
std::cerr << res.Failure() << std::endl;
__builtin_trap();
}
auto dst = tint::wgsl::writer::IRToProgram(ir.Get());
if (!dst.IsValid()) {
#if TINT_BUILD_WGSL_WRITER
if (auto result = tint::wgsl::writer::Generate(dst, {}); result) {
std::cerr << result->wgsl << std::endl << std::endl;
}
#endif
std::cerr << dst.Diagnostics() << std::endl;
__builtin_trap();
}
return 0;
}