Have Program::IsValid() return false unless built

An unbuilt program doesn't have an ast::Module, so Program::AST() will just explode.

* Have a Program default to false for IsValid()
* Initialize the ast_ field to nullptr. This was previously floating.
* Return from CommonFuzzer::Run() earlier if the InputFormat is not recognised.

Fixed: chromium:1180130
Fixed: chromium:1180157
Change-Id: I9b67daa10746f386f44919a7b9ac5c171092d6e5
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/42028
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: David Neto <dneto@google.com>
diff --git a/fuzzers/tint_common_fuzzer.cc b/fuzzers/tint_common_fuzzer.cc
index cbabde2..9e68902 100644
--- a/fuzzers/tint_common_fuzzer.cc
+++ b/fuzzers/tint_common_fuzzer.cc
@@ -42,19 +42,17 @@
 #endif  // TINT_BUILD_WGSL_READER
 
   switch (input_) {
-    case InputFormat::kWGSL:
 #if TINT_BUILD_WGSL_READER
-    {
+    case InputFormat::kWGSL: {
       std::string str(reinterpret_cast<const char*>(data), size);
 
       file = std::make_unique<Source::File>("test.wgsl", str);
       program = reader::wgsl::Parse(file.get());
+      break;
     }
 #endif  // TINT_BUILD_WGSL_READER
-    break;
-    case InputFormat::kSpv:
 #if TINT_BUILD_SPV_READER
-    {
+    case InputFormat::kSpv: {
       size_t sizeInU32 = size / sizeof(uint32_t);
       const uint32_t* u32Data = reinterpret_cast<const uint32_t*>(data);
       std::vector<uint32_t> input(u32Data, u32Data + sizeInU32);
@@ -62,11 +60,11 @@
       if (input.size() != 0) {
         program = reader::spirv::Parse(input);
       }
+      break;
     }
 #endif  // TINT_BUILD_WGSL_READER
-    break;
     default:
-      break;
+      return 0;
   }
 
   if (output_ == OutputFormat::kNone) {
diff --git a/src/program.h b/src/program.h
index 9392923..b4b4b83 100644
--- a/src/program.h
+++ b/src/program.h
@@ -160,11 +160,11 @@
   type::Manager types_;
   ASTNodeAllocator ast_nodes_;
   SemNodeAllocator sem_nodes_;
-  ast::Module* ast_;
+  ast::Module* ast_ = nullptr;
   semantic::Info sem_;
   SymbolTable symbols_;
   diag::List diagnostics_;
-  bool is_valid_ = true;
+  bool is_valid_ = false;  // Not valid until it is built
   bool moved_ = false;
 };
 
diff --git a/src/program_test.cc b/src/program_test.cc
index 9dd64b5..ddf6ce5 100644
--- a/src/program_test.cc
+++ b/src/program_test.cc
@@ -31,6 +31,11 @@
 
 using ProgramTest = ast::TestHelper;
 
+TEST_F(ProgramTest, Unbuilt) {
+  Program program;
+  EXPECT_FALSE(program.IsValid());
+}
+
 TEST_F(ProgramTest, Creation) {
   Program program(std::move(*this));
   EXPECT_EQ(program.AST().Functions().size(), 0u);