Run SubstituteOverrides in fuzzers if needed.

With the change to remove support for `Override` in the various
backends, it is now possible for the fuzzers to send invalid programs
through to the generators by creating overrides.

This CL adds the `SubstituteOverride` transform into the fuzzers and
defaults any non-initialized override to 0. The transform is run
separate from the other transforms used by the fuzzers as the fuzzers
don't have to add transforms, this makes sure the substitution always
happens, regardless of other transform configuration.

Bug: chromium:1362815
Change-Id: I3c57128d24c5613079a62309f5d5edefa28e8413
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/102840
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/fuzzers/tint_common_fuzzer.cc b/src/tint/fuzzers/tint_common_fuzzer.cc
index f547d55..9e12a12 100644
--- a/src/tint/fuzzers/tint_common_fuzzer.cc
+++ b/src/tint/fuzzers/tint_common_fuzzer.cc
@@ -197,8 +197,7 @@
     RunInspector(&program);
     diagnostics_ = program.Diagnostics();
 
-    if (transform_manager_) {
-        auto out = transform_manager_->Run(&program, *transform_inputs_);
+    auto validate_program = [&](auto& out) {
         if (!out.program.IsValid()) {
             // Transforms can produce error messages for bad input.
             // Catch ICEs and errors from non transform systems.
@@ -214,6 +213,45 @@
 
         program = std::move(out.program);
         RunInspector(&program);
+
+        return 1;
+    };
+
+    if (transform_manager_) {
+        auto out = transform_manager_->Run(&program, *transform_inputs_);
+        if (!validate_program(out)) {
+            return 0;
+        }
+    }
+
+    {
+        // Run SubstituteOverride if required
+
+        transform::SubstituteOverride::Config cfg;
+        inspector::Inspector inspector(&program);
+        auto default_values = inspector.GetOverrideDefaultValues();
+        for (const auto& [override_id, scalar] : default_values) {
+            // If the override is not null, then it has a default value, we can just let it use the
+            // provided default instead of overriding.
+            if (!scalar.IsNull()) {
+                continue;
+            }
+
+            cfg.map.insert({override_id, 0.0});
+        }
+
+        if (!cfg.map.empty()) {
+            transform::DataMap override_data;
+            override_data.Add<transform::SubstituteOverride::Config>(cfg);
+
+            transform::Manager mgr;
+            mgr.append(std::make_unique<transform::SubstituteOverride>());
+
+            auto out = mgr.Run(&program, override_data);
+            if (!validate_program(out)) {
+                return 0;
+            }
+        }
     }
 
     switch (output_) {