[tint][ir] Gracefully handle Type() returning null in disassembler
Adds in a `NameOf()` implementation for `type::Type*` that handles
nulls. This is used to replace a bunch of potentially invalid
calls when building output text.
Also:
-Adds in some missing checks for loop initializer and continuing
blocks.
- Adds some missing null checks for usage of `Foo()->` pattern.
Fixes: 356297569
Change-Id: I3c8ae43cdefdd41ab1cf4954af100fbb4fa8fb47
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/200654
Auto-Submit: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: dan sinclair <dsinclair@google.com>
Commit-Queue: Ryan Harrison <rharrison@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/disassembler.cc b/src/tint/lang/core/ir/disassembler.cc
index c6f4bac..ac1fba4 100644
--- a/src/tint/lang/core/ir/disassembler.cc
+++ b/src/tint/lang/core/ir/disassembler.cc
@@ -182,7 +182,7 @@
EmitValue(p);
psm.Store(p);
}
- out_ << ":" << StyleType(p->Type()->FriendlyName());
+ out_ << ":" << NameOf(p->Type());
}
out_ << ")";
}
@@ -338,12 +338,12 @@
out_ << ", ";
}
SourceMarker sm(this);
- out_ << NameOf(p) << ":" << StyleType(p->Type() ? p->Type()->FriendlyName() : "undef");
+ out_ << NameOf(p) << ":" << NameOf(p->Type());
sm.Store(p);
EmitParamAttributes(p);
}
- out_ << "):" << StyleType(func->ReturnType()->FriendlyName());
+ out_ << "):" << NameOf(func->ReturnType());
EmitReturnAttributes(func);
@@ -388,12 +388,7 @@
void Disassembler::EmitValueWithType(const Value* val) {
EmitValue(val);
if (val) {
- out_ << ":";
- if (val->Type()) {
- out_ << StyleType(val->Type()->FriendlyName());
- } else {
- out_ << StyleType("null");
- }
+ out_ << ":" << NameOf(val->Type());
}
}
@@ -425,12 +420,12 @@
out_ << StyleLiteral((scalar->ValueAs<bool>() ? "true" : "false"));
},
[&](const core::constant::Splat* splat) {
- out_ << StyleType(splat->Type()->FriendlyName()) << "(";
+ out_ << NameOf(splat->Type()) << "(";
emit(splat->Index(0));
out_ << ")";
},
[&](const core::constant::Composite* composite) {
- out_ << StyleType(composite->Type()->FriendlyName()) << "(";
+ out_ << NameOf(composite->Type()) << "(";
bool need_comma = false;
for (const auto* elem : composite->elements) {
if (need_comma) {
@@ -641,7 +636,7 @@
out_ << StyleInstruction("if") << " ";
EmitOperand(if_, If::kConditionOperandOffset);
- bool has_false = !if_->False()->IsEmpty();
+ bool has_false = if_->False() != nullptr && !if_->False()->IsEmpty();
out_ << " [" << StyleKeyword("t") << ": " << NameOf(if_->True());
if (has_false) {
@@ -691,14 +686,14 @@
}
out_ << StyleInstruction("loop") << " [";
- if (!l->Initializer()->IsEmpty()) {
+ if (l->Initializer() != nullptr && !l->Initializer()->IsEmpty()) {
out_ << StyleKeyword("i") << ": " << NameOf(l->Initializer());
out_ << ", ";
}
out_ << StyleKeyword("b") << ": " << NameOf(l->Body());
- if (!l->Continuing()->IsEmpty()) {
+ if (l->Continuing() != nullptr && !l->Continuing()->IsEmpty()) {
out_ << ", ";
out_ << StyleKeyword("c") << ": " << NameOf(l->Continuing());
}
@@ -709,18 +704,17 @@
out_ << " { " << StyleComment("# ", NameOf(l));
EmitLine();
- if (!l->Initializer()->IsEmpty()) {
+ if (l->Initializer() != nullptr && !l->Initializer()->IsEmpty()) {
ScopedIndent si(indent_size_);
EmitBlock(l->Initializer(), "initializer");
}
- // Loop is assumed to always have a body
- {
+ if (l->Body() != nullptr) {
ScopedIndent si(indent_size_);
EmitBlock(l->Body(), "body");
}
- if (!l->Continuing()->IsEmpty()) {
+ if (l->Continuing() != nullptr && !l->Continuing()->IsEmpty()) {
ScopedIndent si(indent_size_);
EmitBlock(l->Continuing(), "continuing");
}
@@ -852,7 +846,8 @@
", f: ", NameOf(bi->Loop() ? bi->Loop()->Body() : nullptr), "]");
},
[&](const ir::Continue* c) {
- out_ << " " << StyleComment("# -> ", NameOf(c->Loop()->Continuing()));
+ out_ << " "
+ << StyleComment("# -> ", NameOf(c->Loop() ? c->Loop()->Continuing() : nullptr));
}, //
[&](const ir::ExitIf* e) { out_ << " " << StyleComment("# ", NameOf(e->If())); }, //
[&](const ir::ExitSwitch* e) {
@@ -892,8 +887,7 @@
out_ << " {";
EmitLine();
for (auto* member : str->Members()) {
- out_ << " " << StyleVariable(member->Name().Name()) << ":"
- << StyleType(member->Type()->FriendlyName());
+ out_ << " " << StyleVariable(member->Name().Name()) << ":" << NameOf(member->Type());
out_ << " " << StyleAttribute("@offset") << "(" << StyleLiteral(member->Offset()) << ")";
if (member->Attributes().invariant) {
out_ << ", " << StyleAttribute("@invariant");
@@ -925,6 +919,14 @@
EmitLine();
}
+StyledText Disassembler::NameOf(const type::Type* ty) {
+ if (!ty) {
+ return StyledText{} << StyleError("undef");
+ }
+
+ return StyledText{} << StyleType(ty->FriendlyName());
+}
+
StyledText Disassembler::NameOf(const Block* node) {
if (!node) {
return StyledText{} << StyleError("undef");
diff --git a/src/tint/lang/core/ir/disassembler.h b/src/tint/lang/core/ir/disassembler.h
index b96f496..53e8fcc 100644
--- a/src/tint/lang/core/ir/disassembler.h
+++ b/src/tint/lang/core/ir/disassembler.h
@@ -94,6 +94,9 @@
/// @returns the disassembly file
const std::shared_ptr<Source::File>& File() const { return file_; }
+ /// @returns the disassembled name for the Type @p ty
+ StyledText NameOf(const type::Type* ty);
+
/// @returns the disassembled name for the Block @p blk
StyledText NameOf(const Block* blk);
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index 1ba3dcc..2b4a95a 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -2320,8 +2320,8 @@
ASSERT_NE(res, Success);
EXPECT_EQ(res.Failure().reason.Str(),
R"(:4:5 error: load: result type is undefined
- %3:null = load %i
- ^^^^^^^
+ %3:undef = load %i
+ ^^^^^^^^
:2:3 note: in block
$B1: {
@@ -2339,7 +2339,7 @@
%my_func = func():void {
$B1: {
%i:ptr<function, f32, read_write> = var, 0.0f
- %3:null = load %i
+ %3:undef = load %i
%j:ptr<function, f32, read_write> = var, %3
ret
}
@@ -5781,7 +5781,7 @@
%my_func = func():void {
$B1: {
%2:ptr<function, i32, read_write> = var
- %3:null = construct 42u
+ %3:undef = construct 42u
store %2, %3
ret
}