tint/resolver: Fix ICE in ResolvedIdentifier::String()

That resolve to parameters.

Bug: chromium:1417513
Change-Id: Id7722524acbd9a9a26543cb73f48c8823dd51356
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/120840
Kokoro: Ben Clayton <bclayton@chromium.org>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@chromium.org>
This commit is contained in:
Ben Clayton 2023-02-21 21:07:35 +00:00 committed by Dawn LUCI CQ
parent f0b4dbb82d
commit fdef033210
2 changed files with 70 additions and 29 deletions

View File

@ -878,6 +878,9 @@ std::string ResolvedIdentifier::String(const SymbolTable& symbols, diag::List& d
[&](const ast::Function* n) { // [&](const ast::Function* n) { //
return "function '" + symbols.NameFor(n->name->symbol) + "'"; return "function '" + symbols.NameFor(n->name->symbol) + "'";
}, },
[&](const ast::Parameter* n) { //
return "parameter '" + symbols.NameFor(n->name->symbol) + "'";
},
[&](Default) { [&](Default) {
TINT_UNREACHABLE(Resolver, diagnostics) TINT_UNREACHABLE(Resolver, diagnostics)
<< "unhandled ast::Node: " << node->TypeInfo().name; << "unhandled ast::Node: " << node->TypeInfo().name;

View File

@ -31,6 +31,7 @@ enum class Def {
kFunction, kFunction,
kInterpolationSampling, kInterpolationSampling,
kInterpolationType, kInterpolationType,
kParameter,
kStruct, kStruct,
kTexelFormat, kTexelFormat,
kTypeAlias, kTypeAlias,
@ -55,6 +56,8 @@ std::ostream& operator<<(std::ostream& out, Def def) {
return out << "Def::kInterpolationSampling"; return out << "Def::kInterpolationSampling";
case Def::kInterpolationType: case Def::kInterpolationType:
return out << "Def::kInterpolationType"; return out << "Def::kInterpolationType";
case Def::kParameter:
return out << "Def::kParameter";
case Def::kStruct: case Def::kStruct:
return out << "Def::kStruct"; return out << "Def::kStruct";
case Def::kTexelFormat: case Def::kTexelFormat:
@ -138,6 +141,11 @@ using ResolverExpressionKindTest = ResolverTestWithParam<Case>;
TEST_P(ResolverExpressionKindTest, Test) { TEST_P(ResolverExpressionKindTest, Test) {
Symbol sym; Symbol sym;
std::function<void(const sem::Expression*)> check_expr; std::function<void(const sem::Expression*)> check_expr;
utils::Vector<const ast::Parameter*, 2> fn_params;
utils::Vector<const ast::Statement*, 2> fn_stmts;
utils::Vector<const ast::Attribute*, 2> fn_attrs;
switch (GetParam().def) { switch (GetParam().def) {
case Def::kAccess: { case Def::kAccess: {
sym = Sym("write"); sym = Sym("write");
@ -185,8 +193,8 @@ TEST_P(ResolverExpressionKindTest, Test) {
break; break;
} }
case Def::kFunction: { case Def::kFunction: {
auto* fn = Func(kDefSource, "FUNCTION", utils::Empty, ty.i32(), Return(1_i));
sym = Sym("FUNCTION"); sym = Sym("FUNCTION");
auto* fn = Func(kDefSource, sym, utils::Empty, ty.i32(), Return(1_i));
check_expr = [fn](const sem::Expression* expr) { check_expr = [fn](const sem::Expression* expr) {
ASSERT_NE(expr, nullptr); ASSERT_NE(expr, nullptr);
auto* fn_expr = expr->As<sem::FunctionExpression>(); auto* fn_expr = expr->As<sem::FunctionExpression>();
@ -217,9 +225,21 @@ TEST_P(ResolverExpressionKindTest, Test) {
}; };
break; break;
} }
case Def::kParameter: {
sym = Sym("PARAMETER");
auto* param = Param(kDefSource, sym, ty.i32());
fn_params.Push(param);
check_expr = [param](const sem::Expression* expr) {
ASSERT_NE(expr, nullptr);
auto* user = expr->As<sem::VariableUser>();
ASSERT_NE(user, nullptr);
EXPECT_EQ(user->Variable()->Declaration(), param);
};
break;
}
case Def::kStruct: { case Def::kStruct: {
auto* s = Structure(kDefSource, "STRUCT", utils::Vector{Member("m", ty.i32())});
sym = Sym("STRUCT"); sym = Sym("STRUCT");
auto* s = Structure(kDefSource, sym, utils::Vector{Member("m", ty.i32())});
check_expr = [s](const sem::Expression* expr) { check_expr = [s](const sem::Expression* expr) {
ASSERT_NE(expr, nullptr); ASSERT_NE(expr, nullptr);
auto* ty_expr = expr->As<sem::TypeExpression>(); auto* ty_expr = expr->As<sem::TypeExpression>();
@ -241,8 +261,8 @@ TEST_P(ResolverExpressionKindTest, Test) {
break; break;
} }
case Def::kTypeAlias: { case Def::kTypeAlias: {
Alias(kDefSource, "ALIAS", ty.i32());
sym = Sym("ALIAS"); sym = Sym("ALIAS");
Alias(kDefSource, sym, ty.i32());
check_expr = [](const sem::Expression* expr) { check_expr = [](const sem::Expression* expr) {
ASSERT_NE(expr, nullptr); ASSERT_NE(expr, nullptr);
auto* ty_expr = expr->As<sem::TypeExpression>(); auto* ty_expr = expr->As<sem::TypeExpression>();
@ -252,8 +272,8 @@ TEST_P(ResolverExpressionKindTest, Test) {
break; break;
} }
case Def::kVariable: { case Def::kVariable: {
auto* c = GlobalConst(kDefSource, "VARIABLE", Expr(1_i));
sym = Sym("VARIABLE"); sym = Sym("VARIABLE");
auto* c = GlobalConst(kDefSource, sym, Expr(1_i));
check_expr = [c](const sem::Expression* expr) { check_expr = [c](const sem::Expression* expr) {
ASSERT_NE(expr, nullptr); ASSERT_NE(expr, nullptr);
auto* var_expr = expr->As<sem::VariableUser>(); auto* var_expr = expr->As<sem::VariableUser>();
@ -271,62 +291,67 @@ TEST_P(ResolverExpressionKindTest, Test) {
break; break;
case Use::kAddressSpace: case Use::kAddressSpace:
Enable(builtin::Extension::kChromiumExperimentalFullPtrParameters); Enable(builtin::Extension::kChromiumExperimentalFullPtrParameters);
Func("f", utils::Vector{Param("p", ty("ptr", expr, ty.f32()))}, ty.void_(), Func(Symbols().New(), utils::Vector{Param("p", ty("ptr", expr, ty.f32()))}, ty.void_(),
utils::Empty); utils::Empty);
break; break;
case Use::kCallExpr: case Use::kCallExpr:
Func("f", utils::Empty, ty.void_(), Decl(Var("v", Call(expr)))); fn_stmts.Push(Decl(Var("v", Call(expr))));
break; break;
case Use::kCallStmt: case Use::kCallStmt:
Func("f", utils::Empty, ty.void_(), CallStmt(Call(expr))); fn_stmts.Push(CallStmt(Call(expr)));
break; break;
case Use::kBinaryOp: case Use::kBinaryOp:
GlobalVar("v", builtin::AddressSpace::kPrivate, Mul(1_a, expr)); fn_stmts.Push(Decl(Var("v", Mul(1_a, expr))));
break; break;
case Use::kBuiltinValue: case Use::kBuiltinValue:
Func("f", utils::Vector{Param("p", ty.vec4<f32>(), utils::Vector{Builtin(expr)})}, Func(Symbols().New(),
utils::Vector{Param("p", ty.vec4<f32>(), utils::Vector{Builtin(expr)})},
ty.void_(), utils::Empty, utils::Vector{Stage(ast::PipelineStage::kFragment)}); ty.void_(), utils::Empty, utils::Vector{Stage(ast::PipelineStage::kFragment)});
break; break;
case Use::kFunctionReturnType: case Use::kFunctionReturnType:
Func("f", utils::Empty, ty(expr), Return(Call(sym))); Func(Symbols().New(), utils::Empty, ty(expr), Return(Call(sym)));
break; break;
case Use::kInterpolationSampling: { case Use::kInterpolationSampling: {
Func("f", fn_params.Push(Param("p", ty.vec4<f32>(),
utils::Vector{Param("p", ty.vec4<f32>(), utils::Vector{
utils::Vector{ Location(0_a),
Location(0_a), Interpolate(builtin::InterpolationType::kLinear, expr),
Interpolate(builtin::InterpolationType::kLinear, expr), }));
})}, fn_attrs.Push(Stage(ast::PipelineStage::kFragment));
ty.void_(), utils::Empty, utils::Vector{Stage(ast::PipelineStage::kFragment)});
break; break;
} }
case Use::kInterpolationType: { case Use::kInterpolationType: {
Func("f", fn_params.Push(Param("p", ty.vec4<f32>(),
utils::Vector{Param("p", ty.vec4<f32>(), utils::Vector{
utils::Vector{ Location(0_a),
Location(0_a), Interpolate(expr, builtin::InterpolationSampling::kCenter),
Interpolate(expr, builtin::InterpolationSampling::kCenter), }));
})}, fn_attrs.Push(Stage(ast::PipelineStage::kFragment));
ty.void_(), utils::Empty, utils::Vector{Stage(ast::PipelineStage::kFragment)});
break; break;
} }
case Use::kMemberType: case Use::kMemberType:
Structure("s", utils::Vector{Member("m", ty(expr))}); Structure(Symbols().New(), utils::Vector{Member("m", ty(expr))});
break; break;
case Use::kTexelFormat: case Use::kTexelFormat:
GlobalVar("v", ty("texture_storage_2d", ty(expr), "write"), Group(0_u), Binding(0_u)); GlobalVar(Symbols().New(), ty("texture_storage_2d", ty(expr), "write"), Group(0_u),
Binding(0_u));
break; break;
case Use::kValueExpression: case Use::kValueExpression:
GlobalVar("v", builtin::AddressSpace::kPrivate, expr); fn_stmts.Push(Decl(Var("v", expr)));
break; break;
case Use::kVariableType: case Use::kVariableType:
GlobalVar("v", builtin::AddressSpace::kPrivate, ty(expr)); fn_stmts.Push(Decl(Var("v", ty(expr))));
break; break;
case Use::kUnaryOp: case Use::kUnaryOp:
GlobalVar("v", builtin::AddressSpace::kPrivate, Negation(expr)); fn_stmts.Push(Assign(Phony(), Negation(expr)));
break; break;
} }
if (!fn_params.IsEmpty() || !fn_stmts.IsEmpty()) {
Func(Symbols().New(), std::move(fn_params), ty.void_(), std::move(fn_stmts),
std::move(fn_attrs));
}
if (GetParam().error == kPass) { if (GetParam().error == kPass) {
EXPECT_TRUE(r()->Resolve()); EXPECT_TRUE(r()->Resolve());
EXPECT_EQ(r()->error(), ""); EXPECT_EQ(r()->error(), "");
@ -560,6 +585,19 @@ INSTANTIATE_TEST_SUITE_P(
{Def::kInterpolationType, Use::kUnaryOp, {Def::kInterpolationType, Use::kUnaryOp,
R"(5:6 error: cannot use interpolation type 'linear' as value)"}, R"(5:6 error: cannot use interpolation type 'linear' as value)"},
{Def::kParameter, Use::kBinaryOp, kPass},
{Def::kParameter, Use::kCallStmt,
R"(5:6 error: cannot use parameter 'PARAMETER' as call target
1:2 note: parameter 'PARAMETER' declared here)"},
{Def::kParameter, Use::kCallExpr,
R"(5:6 error: cannot use parameter 'PARAMETER' as call target
1:2 note: parameter 'PARAMETER' declared here)"},
{Def::kParameter, Use::kValueExpression, kPass},
{Def::kParameter, Use::kVariableType,
R"(5:6 error: cannot use parameter 'PARAMETER' as type
1:2 note: parameter 'PARAMETER' declared here)"},
{Def::kParameter, Use::kUnaryOp, kPass},
{Def::kStruct, Use::kAccess, R"(5:6 error: cannot use type 'STRUCT' as access)"}, {Def::kStruct, Use::kAccess, R"(5:6 error: cannot use type 'STRUCT' as access)"},
{Def::kStruct, Use::kAddressSpace, {Def::kStruct, Use::kAddressSpace,
R"(5:6 error: cannot use type 'STRUCT' as address space)"}, R"(5:6 error: cannot use type 'STRUCT' as address space)"},