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());
}
}
}