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>
This commit is contained in:
Ben Clayton 2023-04-24 13:49:00 +00:00 committed by Dawn LUCI CQ
parent 71007c7109
commit d14a9fbb6e
3 changed files with 15 additions and 6 deletions

View File

@ -3115,13 +3115,14 @@ sem::Expression* Resolver::Identifier(const ast::IdentifierExpression* expr) {
} }
sem::ValueExpression* Resolver::MemberAccessor(const ast::MemberAccessorExpression* expr) { 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); auto* object = sem_.GetVal(expr->object);
if (!object) { if (!object) {
return nullptr; return nullptr;
} }
auto* object_ty = object->Type();
auto* storage_ty = object_ty->UnwrapRef();
auto* root_ident = object->RootIdentifier(); auto* root_ident = object->RootIdentifier();
const type::Type* ty = nullptr; const type::Type* ty = nullptr;
@ -3152,7 +3153,7 @@ sem::ValueExpression* Resolver::MemberAccessor(const ast::MemberAccessorExpressi
ty = member->Type(); ty = member->Type();
// If we're extracting from a reference, we return a reference. // 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()); ty = builder_->create<type::Reference>(ty, ref->AddressSpace(), ref->Access());
} }
@ -3221,7 +3222,7 @@ sem::ValueExpression* Resolver::MemberAccessor(const ast::MemberAccessorExpressi
// A single element swizzle is just the type of the vector. // A single element swizzle is just the type of the vector.
ty = vec->type(); ty = vec->type();
// If we're extracting from a reference, we return a reference. // 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()); ty = builder_->create<type::Reference>(ty, ref->AddressSpace(), ref->Access());
} }
} else { } else {

View File

@ -1239,6 +1239,15 @@ TEST_F(ResolverTest, Function_WorkgroupSize_Mixed) {
EXPECT_EQ(func_sem->WorkgroupSize()[2], 3u); 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) { TEST_F(ResolverTest, Expr_MemberAccessor_Struct) {
auto* st = Structure( auto* st = Structure(
"S", utils::Vector{Member("first_member", ty.i32()), Member("second_member", ty.f32())}); "S", utils::Vector{Member("first_member", ty.i32()), Member("second_member", ty.f32())});

View File

@ -105,8 +105,7 @@ void SemHelper::ErrorExpectedValueExpr(const sem::Expression* expr) const {
ErrorUnexpectedExprKind(expr, "value"); ErrorUnexpectedExprKind(expr, "value");
if (auto* ty_expr = expr->As<sem::TypeExpression>()) { if (auto* ty_expr = expr->As<sem::TypeExpression>()) {
if (auto* ident = ty_expr->Declaration()->As<ast::IdentifierExpression>()) { if (auto* ident = ty_expr->Declaration()->As<ast::IdentifierExpression>()) {
AddNote("are you missing '()' for value constructor?", AddNote("are you missing '()' for value constructor?", ident->source.End());
Source{{ident->source.range.end}});
} }
} }
} }