Add TINT_UNREACHABLE() and TINT_ICE() helper macros

Appends an error message with the tint compiler source location to the
provided diagnositic list, and then calls the global error handler if
one is set.
Tests and the sample app now register an error handler to print the
diagnostic list to stderr and abort when NDEBUG is not defined.

All uses of assert(false) have been fixed up to use these macros.

Change-Id: I2f63e51ed86ac23883301d280070bd1a357c6cb2
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/41620
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton
2021-02-17 20:13:34 +00:00
committed by Commit Bot service account
parent c7ca7668cc
commit 6b4924fb0e
35 changed files with 858 additions and 476 deletions

View File

@@ -14,6 +14,8 @@
#include "src/diagnostic/diagnostic.h"
#include "src/diagnostic/formatter.h"
namespace tint {
namespace diag {
@@ -27,5 +29,11 @@ List::~List() = default;
List& List::operator=(const List&) = default;
List& List::operator=(List&&) = default;
std::string List::str() const {
diag::Formatter::Style style;
style.print_newline_at_end = false;
return Formatter{style}.format(*this);
}
} // namespace diag
} // namespace tint

View File

@@ -15,6 +15,7 @@
#ifndef SRC_DIAGNOSTIC_DIAGNOSTIC_H_
#define SRC_DIAGNOSTIC_DIAGNOSTIC_H_
#include <cassert>
#include <initializer_list>
#include <string>
#include <utility>
@@ -26,7 +27,7 @@ namespace tint {
namespace diag {
/// Severity is an enumerator of diagnostic severities.
enum class Severity { Info, Warning, Error, Fatal };
enum class Severity { Info, Warning, Error, InternalCompilerError, Fatal };
/// @return true iff `a` is more than, or of equal severity to `b`
inline bool operator>=(Severity a, Severity b) {
@@ -118,6 +119,17 @@ class List {
add(std::move(error));
}
/// adds an internal compiler error message to the end of this list.
/// @param err_msg the error message
/// @param source the source of the internal compiler error
void add_ice(const std::string& err_msg, const Source& source) {
diag::Diagnostic ice{};
ice.severity = diag::Severity::InternalCompilerError;
ice.source = source;
ice.message = err_msg;
add(std::move(ice));
}
/// @returns true iff the diagnostic list contains errors diagnostics (or of
/// higher severity).
bool contains_errors() const { return error_count_ > 0; }
@@ -130,6 +142,9 @@ class List {
/// @returns the last diagnostic in the list.
iterator end() const { return entries_.end(); }
/// @returns a formatted string of all the diagnostics in this list.
std::string str() const;
private:
std::vector<Diagnostic> entries_;
size_t error_count_ = 0;

View File

@@ -33,6 +33,8 @@ const char* to_str(Severity severity) {
return "warning";
case Severity::Error:
return "error";
case Severity::InternalCompilerError:
return "internal compiler error";
case Severity::Fatal:
return "fatal";
}
@@ -112,6 +114,7 @@ Formatter::Formatter(const Style& style) : style_(style) {}
void Formatter::format(const List& list, Printer* printer) const {
State state{printer};
bool please_report_bug = false;
bool first = true;
for (auto diag : list) {
state.set_style({});
@@ -120,7 +123,23 @@ void Formatter::format(const List& list, Printer* printer) const {
}
format(diag, state);
first = false;
if (static_cast<int>(diag.severity) > static_cast<int>(Severity::Error)) {
please_report_bug = true;
}
}
if (please_report_bug) {
state.set_style({Color::kRed, true});
state << R"(
********************************************************************
* The tint shader compiler has encountered an unexpected error. *
* *
* Please help us fix this issue by submitting a bug report at *
* crbug.com/tint with the source program that triggered the bug. *
********************************************************************
)";
}
if (style_.print_newline_at_end) {
state.newline();
}
@@ -154,14 +173,17 @@ void Formatter::format(const Diagnostic& diag, State& state) const {
Color severity_color = Color::kDefault;
switch (diag.severity) {
case Severity::Info:
break;
case Severity::Warning:
severity_color = Color::kYellow;
break;
case Severity::Error:
case Severity::Fatal:
severity_color = Color::kRed;
break;
default:
case Severity::Fatal:
case Severity::InternalCompilerError:
severity_color = Color::kMagenta;
break;
}
if (style_.print_severity) {

View File

@@ -39,6 +39,9 @@ class DiagFormatterTest : public testing::Test {
Diagnostic diag_err{Severity::Error,
Source{Source::Range{{3, 16}, {3, 21}}, &file}, "hiss",
"abc123"};
Diagnostic diag_ice{Severity::InternalCompilerError,
Source{Source::Range{{4, 16}, {4, 19}}, &file},
"unreachable"};
Diagnostic diag_fatal{Severity::Fatal,
Source{Source::Range{{4, 16}, {4, 19}}, &file},
"nothing"};
@@ -46,21 +49,19 @@ class DiagFormatterTest : public testing::Test {
TEST_F(DiagFormatterTest, Simple) {
Formatter fmt{{false, false, false, false}};
auto got = fmt.format(List{diag_info, diag_warn, diag_err, diag_fatal});
auto got = fmt.format(List{diag_info, diag_warn, diag_err});
auto* expect = R"(1:14: purr
2:14: grrr
3:16 abc123: hiss
4:16: nothing)";
3:16 abc123: hiss)";
ASSERT_EQ(expect, got);
}
TEST_F(DiagFormatterTest, SimpleNewlineAtEnd) {
Formatter fmt{{false, false, false, true}};
auto got = fmt.format(List{diag_info, diag_warn, diag_err, diag_fatal});
auto got = fmt.format(List{diag_info, diag_warn, diag_err});
auto* expect = R"(1:14: purr
2:14: grrr
3:16 abc123: hiss
4:16: nothing
)";
ASSERT_EQ(expect, got);
}
@@ -75,27 +76,25 @@ TEST_F(DiagFormatterTest, SimpleNoSource) {
TEST_F(DiagFormatterTest, WithFile) {
Formatter fmt{{true, false, false, false}};
auto got = fmt.format(List{diag_info, diag_warn, diag_err, diag_fatal});
auto got = fmt.format(List{diag_info, diag_warn, diag_err});
auto* expect = R"(file.name:1:14: purr
file.name:2:14: grrr
file.name:3:16 abc123: hiss
file.name:4:16: nothing)";
file.name:3:16 abc123: hiss)";
ASSERT_EQ(expect, got);
}
TEST_F(DiagFormatterTest, WithSeverity) {
Formatter fmt{{false, true, false, false}};
auto got = fmt.format(List{diag_info, diag_warn, diag_err, diag_fatal});
auto got = fmt.format(List{diag_info, diag_warn, diag_err});
auto* expect = R"(1:14 info: purr
2:14 warning: grrr
3:16 error abc123: hiss
4:16 fatal: nothing)";
3:16 error abc123: hiss)";
ASSERT_EQ(expect, got);
}
TEST_F(DiagFormatterTest, WithLine) {
Formatter fmt{{false, false, true, false}};
auto got = fmt.format(List{diag_info, diag_warn, diag_err, diag_fatal});
auto got = fmt.format(List{diag_info, diag_warn, diag_err});
auto* expect = R"(1:14: purr
the cat says meow
^
@@ -107,17 +106,13 @@ the dog says woof
3:16 abc123: hiss
the snake says quack
^^^^^
4:16: nothing
the snail says ???
^^^
)";
ASSERT_EQ(expect, got);
}
TEST_F(DiagFormatterTest, BasicWithFileSeverityLine) {
Formatter fmt{{true, true, true, false}};
auto got = fmt.format(List{diag_info, diag_warn, diag_err, diag_fatal});
auto got = fmt.format(List{diag_info, diag_warn, diag_err});
auto* expect = R"(file.name:1:14 info: purr
the cat says meow
^
@@ -129,10 +124,6 @@ the dog says woof
file.name:3:16 error abc123: hiss
the snake says quack
^^^^^
file.name:4:16 fatal: nothing
the snail says ???
^^^
)";
ASSERT_EQ(expect, got);
}
@@ -154,6 +145,42 @@ the snail says ???
ASSERT_EQ(expect, got);
}
TEST_F(DiagFormatterTest, ICE) {
Formatter fmt{{}};
auto got = fmt.format(List{diag_ice});
auto* expect = R"(file.name:4:16 internal compiler error: unreachable
the snail says ???
^^^
********************************************************************
* The tint shader compiler has encountered an unexpected error. *
* *
* Please help us fix this issue by submitting a bug report at *
* crbug.com/tint with the source program that triggered the bug. *
********************************************************************
)";
ASSERT_EQ(expect, got);
}
TEST_F(DiagFormatterTest, Fatal) {
Formatter fmt{{}};
auto got = fmt.format(List{diag_fatal});
auto* expect = R"(file.name:4:16 fatal: nothing
the snail says ???
^^^
********************************************************************
* The tint shader compiler has encountered an unexpected error. *
* *
* Please help us fix this issue by submitting a bug report at *
* crbug.com/tint with the source program that triggered the bug. *
********************************************************************
)";
ASSERT_EQ(expect, got);
}
} // namespace
} // namespace diag
} // namespace tint