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:
parent
f0b4dbb82d
commit
fdef033210
|
@ -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;
|
||||||
|
|
|
@ -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)"},
|
||||||
|
|
Loading…
Reference in New Issue