tint/resolver: Fix null deref

When attempting to member-access a non-value expression.

GetVal() ensures the expression resolves to a value expression, and errors accordingly.

Bug: chromium:1436467
Change-Id: I77ebb44f836be3b99db4b5c26ff41db2ee3fe30a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/128840
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index 19571a7..58050b9 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -3115,13 +3115,14 @@
 }
 
 sem::ValueExpression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* expr) {
-    auto* structure = sem_.TypeOf(expr->object);
-    auto* storage_ty = structure->UnwrapRef();
     auto* object = sem_.GetVal(expr->object);
     if (!object) {
         return nullptr;
     }
 
+    auto* object_ty = object->Type();
+    auto* storage_ty = object_ty->UnwrapRef();
+
     auto* root_ident = object->RootIdentifier();
 
     const type::Type* ty = nullptr;
@@ -3152,7 +3153,7 @@
             ty = member->Type();
 
             // If we're extracting from a reference, we return a reference.
-            if (auto* ref = structure->As<type::Reference>()) {
+            if (auto* ref = object_ty->As<type::Reference>()) {
                 ty = builder_->create<type::Reference>(ty, ref->AddressSpace(), ref->Access());
             }
 
@@ -3221,7 +3222,7 @@
                 // A single element swizzle is just the type of the vector.
                 ty = vec->type();
                 // If we're extracting from a reference, we return a reference.
-                if (auto* ref = structure->As<type::Reference>()) {
+                if (auto* ref = object_ty->As<type::Reference>()) {
                     ty = builder_->create<type::Reference>(ty, ref->AddressSpace(), ref->Access());
                 }
             } else {
diff --git a/src/tint/resolver/resolver_test.cc b/src/tint/resolver/resolver_test.cc
index a601ef0..5df2fae 100644
--- a/src/tint/resolver/resolver_test.cc
+++ b/src/tint/resolver/resolver_test.cc
@@ -1239,6 +1239,15 @@
     EXPECT_EQ(func_sem->WorkgroupSize()[2], 3u);
 }
 
+TEST_F(ResolverTest, Expr_MemberAccessor_Type) {
+    auto* mem = MemberAccessor(Ident(Source{{12, 34}}, "f32"), "member");
+    WrapInFunction(mem);
+
+    EXPECT_FALSE(r()->Resolve()) << r()->error();
+    EXPECT_EQ(r()->error(), R"(12:34 error: cannot use type 'f32' as value
+12:34 note: are you missing '()' for value constructor?)");
+}
+
 TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
     auto* st = Structure(
         "S", utils::Vector{Member("first_member", ty.i32()), Member("second_member", ty.f32())});
diff --git a/src/tint/resolver/sem_helper.cc b/src/tint/resolver/sem_helper.cc
index 2357ce1..dd2341f 100644
--- a/src/tint/resolver/sem_helper.cc
+++ b/src/tint/resolver/sem_helper.cc
@@ -105,8 +105,7 @@
     ErrorUnexpectedExprKind(expr, "value");
     if (auto* ty_expr = expr->As<sem::TypeExpression>()) {
         if (auto* ident = ty_expr->Declaration()->As<ast::IdentifierExpression>()) {
-            AddNote("are you missing '()' for value constructor?",
-                    Source{{ident->source.range.end}});
+            AddNote("are you missing '()' for value constructor?", ident->source.End());
         }
     }
 }