resolver: Always validate return statements

Previously we were only validating return statements that had values,
which meant we were not catching issues when the return value was
omitted in a non-void function.

Fixed: chromium:1219037
Change-Id: If68f67a4a79e46894eee08322726000074c9095b
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/54561
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: James Price <jrprice@google.com>
Auto-Submit: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/resolver/function_validation_test.cc b/src/resolver/function_validation_test.cc
index 4cbd7ae..4f0cf40 100644
--- a/src/resolver/function_validation_test.cc
+++ b/src/resolver/function_validation_test.cc
@@ -201,6 +201,21 @@
 }
 
 TEST_F(ResolverFunctionValidationTest,
+       FunctionTypeMustMatchReturnStatementTypeMissing_fail) {
+  // fn func -> f32 { return; }
+  Func("func", ast::VariableList{}, ty.f32(),
+       ast::StatementList{
+           Return(Source{Source::Location{12, 34}}, nullptr),
+       },
+       ast::DecorationList{});
+
+  EXPECT_FALSE(r()->Resolve());
+  EXPECT_EQ(r()->error(),
+            "12:34 error v-000y: return statement type must match its function "
+            "return type, returned 'void', expected 'f32'");
+}
+
+TEST_F(ResolverFunctionValidationTest,
        FunctionTypeMustMatchReturnStatementTypeF32_pass) {
   // fn func -> f32 { return 2.0; }
   Func("func", ast::VariableList{}, ty.f32(),
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index 5a4d48e..4ba075d 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -3189,13 +3189,14 @@
 
   if (auto* value = ret->value()) {
     Mark(value);
-
-    // Validate after processing the return value expression so that its type
-    // is available for validation
-    return Expression(value) && ValidateReturn(ret);
+    if (!Expression(value)) {
+      return false;
+    }
   }
 
-  return true;
+  // Validate after processing the return value expression so that its type is
+  // available for validation.
+  return ValidateReturn(ret);
 }
 
 bool Resolver::ValidateSwitch(const ast::SwitchStatement* s) {