Skip to content

Commit e31e6f2

Browse files
authored
[TableGen] Print assert message inline with assert failure (#111184)
Print assert message after the "assertion failed" message instead of printing it as a separate note. This makes the assert failure reporting less verbose and also more useful to see the failure message inline with the "assertion failed" message.
1 parent 72f3804 commit e31e6f2

File tree

2 files changed

+30
-65
lines changed

2 files changed

+30
-65
lines changed

llvm/lib/TableGen/Error.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,24 +168,21 @@ bool CheckAssert(SMLoc Loc, Init *Condition, Init *Message) {
168168
return true;
169169
}
170170
if (!CondValue->getValue()) {
171-
PrintError(Loc, "assertion failed");
172-
if (auto *MessageInit = dyn_cast<StringInit>(Message))
173-
PrintNote(MessageInit->getValue());
174-
else
175-
PrintNote("(assert message is not a string)");
171+
auto *MessageInit = dyn_cast<StringInit>(Message);
172+
StringRef AssertMsg = MessageInit ? MessageInit->getValue()
173+
: "(assert message is not a string)";
174+
PrintError(Loc, "assertion failed: " + AssertMsg);
176175
return true;
177176
}
178177
return false;
179178
}
180179

181180
// Dump a message to stderr.
182181
void dumpMessage(SMLoc Loc, Init *Message) {
183-
auto *MessageInit = dyn_cast<StringInit>(Message);
184-
if (!MessageInit) {
185-
PrintError(Loc, "dump value is not of type string");
186-
} else {
182+
if (auto *MessageInit = dyn_cast<StringInit>(Message))
187183
PrintNote(Loc, MessageInit->getValue());
188-
}
184+
else
185+
PrintError(Loc, "dump value is not of type string");
189186
}
190187

191188
} // end namespace llvm

llvm/test/TableGen/assert.td

Lines changed: 23 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,35 @@
44
// Test the assert statement at top level.
55
// -----------------------------------------------------------------------------
66

7-
// CHECK: assertion failed
7+
// CHECK: [[FILE]]:[[@LINE+4]]:8: error: assertion failed: primary name is too long
88
// CHECK-NOT: note: primary name is too short
9-
// CHECK: note: primary name is too long
10-
119
defvar Name = "Grace Brewster Murray Hopper";
12-
1310
assert !ge(!size(Name), 20), "primary name is too short: " # Name;
1411
assert !le(!size(Name), 20), "primary name is too long: " # Name;
1512

16-
// CHECK: assertion failed
17-
// CHECK: note: first name is incorrect
18-
13+
// CHECK: assertion failed: first name is incorrect
1914
def Rec01 {
2015
string name = "Fred Smith";
2116
}
2217

2318
assert !eq(!substr(Rec01.name, 0, 3), "Jane"),
2419
!strconcat("first name is incorrect: ", Rec01.name);
2520

26-
// CHECK: assertion failed
27-
// CHECK: note: record Rec02 is broken
28-
21+
// CHECK: assertion failed: record Rec02 is broken
2922
def Rec02 {
3023
bit broken = true;
3124
}
32-
3325
assert !not(Rec02.broken), "record Rec02 is broken";
3426

35-
// CHECK: assertion failed
36-
// CHECK: note: cube of 9
37-
27+
// CHECK: assertion failed: cube of 9 should be 729
3828
class Cube<int n> {
3929
int result = !mul(n, n, n);
4030
}
41-
4231
assert !eq(Cube<9>.result, 81), "cube of 9 should be 729";
4332

44-
// CHECK: assertion failed
45-
// CHECK: note: foreach i cannot be 2
46-
// CHECK-NOT: note: foreach i cannot be 2
47-
33+
// Verify that the assert fails only once.
34+
// CHECK: assertion failed: foreach i cannot be 2
35+
// CHECK-NOT: assertion failed: foreach i cannot be 2
4836
foreach i = 1...3 in {
4937
assert !ne(i, 2), "foreach i cannot be 2";
5038
def bar_ # i;
@@ -54,11 +42,9 @@ foreach i = 1...3 in {
5442
// Test the assert statement in a record definition.
5543
// -----------------------------------------------------------------------------
5644

57-
// CHECK: [[FILE]]:[[@LINE+8]]:10: error: assertion failed
45+
// CHECK: [[FILE]]:[[@LINE+6]]:10: error: assertion failed: primary first name is not "Grack"
5846
// CHECK-NOT: primary first name is not "Grace"
59-
// CHECK: note: primary first name is not "Grack"
60-
// CHECK: [[FILE]]:[[@LINE+7]]:10: error: assertion failed
61-
// CHECK: note: foo field should be
47+
// CHECK: [[FILE]]:[[@LINE+6]]:10: error: assertion failed: foo field should be
6248
// CHECK: [[FILE]]:[[@LINE+1]]:5: error: assertion failed in this record
6349
def Rec10 {
6450
assert !eq(!substr(Name, 0, 5), "Grace"), "primary first name is not \"Grace\"";
@@ -67,26 +53,23 @@ def Rec10 {
6753
assert !eq(foo, "foo"), "foo field should be \"Foo\"";
6854
}
6955

70-
// CHECK: [[FILE]]:[[@LINE+5]]:10: error: assertion failed
71-
// CHECK: note: magic field is incorrect: 42
56+
// CHECK: [[FILE]]:[[@LINE+4]]:10: error: assertion failed: magic field is incorrect: 42
7257
// CHECK: [[FILE]]:[[@LINE+1]]:5: error: assertion failed in this record
7358
def Rec11 {
7459
int magic = 13;
7560
assert !eq(magic, 13), "magic field is incorrect: " # magic;
7661
let magic = 42;
7762
}
7863

79-
// CHECK: [[FILE]]:[[@LINE+6]]:10: error: assertion failed
80-
// CHECK: note: var field has wrong value
64+
// CHECK: [[FILE]]:[[@LINE+5]]:10: error: assertion failed: var field has wrong value
8165
// CHECK: [[FILE]]:[[@LINE+1]]:5: error: assertion failed in this record
8266
def Rec12 {
8367
defvar prefix = "foo_";
8468
string var = prefix # "snork";
8569
assert !eq(var, "foo_snorx"), "var field has wrong value: " # var;
8670
}
8771

88-
// CHECK: assertion failed
89-
// CHECK: note: kind field has wrong value
72+
// CHECK: assertion failed: kind field has wrong value
9073
class Kind {
9174
int kind = 7;
9275
}
@@ -97,8 +80,7 @@ def Rec13 : Kind {
9780
assert !eq(kind, 7), "kind field has wrong value: " # kind;
9881
}
9982

100-
// CHECK: assertion failed
101-
// CHECK: note: double_result should be
83+
// CHECK: assertion failed: double_result should be
10284
// CHECK: [[FILE]]:[[@LINE+1]]:5: error: assertion failed in this record
10385
def Rec14 : Cube<3> {
10486
int double_result = !mul(result, 2);
@@ -122,13 +104,11 @@ class Person<string name, int age> : PersonName<name> {
122104

123105
def Rec20 : Person<"Donald Knuth", 60>;
124106

125-
// CHECK: assertion failed
126-
// CHECK: note: person name is too long
107+
// CHECK: assertion failed: person name is too long
127108
// CHECK: [[FILE]]:[[@LINE+1]]:5: error: assertion failed in this record
128109
def Rec21 : Person<"Donald Uh Oh This Name Is Too Long Knuth", 50>;
129110

130-
// CHECK: assertion failed
131-
// CHECK: note: person age is invalid
111+
// CHECK: assertion failed: person age is invalid
132112
// CHECK: [[FILE]]:[[@LINE+1]]:5: error: assertion failed in this record
133113
def Rec22 : Person<"Donald Knuth", 150>;
134114

@@ -138,16 +118,14 @@ def Rec30 {
138118
int Age = Person<"Margaret Heafield Hamilton", 25>.Age;
139119
}
140120

141-
// CHECK: assertion failed
142-
// CHECK: note: person name is too long
121+
// CHECK: assertion failed: person name is too long
143122
// CHECK: [[FILE]]:[[@LINE+2]]:17: error: assertion failed in this record
144123
def Rec31 {
145124
string Name = Person<"Margaret Heafield And More Middle Names Hamilton", 25>.Name;
146125
int Age = Person<"Margaret Heafield Hamilton", 25>.Age;
147126
}
148127

149-
// CHECK: assertion failed
150-
// CHECK: note: person age is invalid: 0
128+
// CHECK: assertion failed: person age is invalid: 0
151129
// CHECK: [[FILE]]:[[@LINE+3]]:13: error: assertion failed in this record
152130
def Rec32 {
153131
string Name = Person<"Margaret Heafield Hamilton", 25>.Name;
@@ -158,11 +136,8 @@ def Rec32 {
158136
// Test the assert statement in a multiclass.
159137
// -----------------------------------------------------------------------------
160138

161-
// CHECK: assertion failed
162-
// CHECK: note: MC1 id string is too long
163-
// CHECK: assertion failed
164-
// CHECK: note: MC1 seq is too high
165-
139+
// CHECK: assertion failed: MC1 id string is too long
140+
// CHECK: assertion failed: MC1 seq is too high
166141
multiclass MC1<string id, int seq> {
167142
assert !le(!size(id), 5), "MC1 id string is too long";
168143
assert !le(seq, 999999), "MC1 seq is too high";
@@ -177,9 +152,7 @@ defm Rec40 : MC1<"ILISP", 999>;
177152
defm Rec41 : MC1<"ILISPX", 999>;
178153
defm Rec42 : MC1<"ILISP", 999999999>;
179154

180-
// CHECK: assertion failed
181-
// CHECK: note: MC2 phrase must be secret: secrex code
182-
155+
// CHECK: assertion failed: MC2 phrase must be secret: secrex code
183156
multiclass MC2<string phr> {
184157
assert !eq(!substr(phr, 0, 6), "secret"), "MC2 phrase must be secret: " # phr;
185158

@@ -194,9 +167,7 @@ multiclass MC3<string phr> {
194167

195168
defm Rec43 : MC3<"secrex code">;
196169

197-
// CHECK: assertion failed
198-
// CHECK: note: MC2 phrase must be secret: xecret code
199-
170+
// CHECK: assertion failed: MC2 phrase must be secret: xecret code
200171
multiclass MC4<string phr> : MC2<phr> {
201172
def _def;
202173
}
@@ -205,11 +176,8 @@ defm Rec44 : MC4<"xecret code">;
205176

206177
// Test a defm in a multiclass that inherits from a class with asserts.
207178

208-
// CHECK: assertion failed
209-
// CHECK: note: MC5 name must include a space: Ada_Lovelace
210-
// CHECK: assertion failed
211-
// CHECK: note: person age is invalid: 666
212-
179+
// CHECK: assertion failed: MC5 name must include a space: Ada_Lovelace
180+
// CHECK: assertion failed: person age is invalid: 666
213181
multiclass MC5<string phr, string name, int age> {
214182
assert !ne(!find(name, " "), -1), "MC5 name must include a space: " # name;
215183

0 commit comments

Comments
 (0)