Skip to content

Commit f5c7b25

Browse files
committed
Compiler: move c2_assert to libs/libc/c2_assert.c2i
* compute the assert string and function call at parse time * add c2_assert module in C library interface libs/libc/c2_assert.c2i * update tests
1 parent 65ad2ea commit f5c7b25

File tree

14 files changed

+84
-57
lines changed

14 files changed

+84
-57
lines changed

analyser/module_analyser_stmt.c2

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,11 @@ fn void Analyser.analyseAssertStmt(Analyser* ma, Stmt* s) {
374374

375375
Expr* inner = a.getInner();
376376
ma.checker.check(builtins[BuiltinKind.Bool], qt, a.getInner2(), inner.getLoc());
377+
378+
if (a.getCall()) {
379+
qt = ma.analyseExpr(a.getCall2(), true, RHS);
380+
if (qt.isInvalid()) return;
381+
}
377382
}
378383

379384
fn void Analyser.analyseReturnStmt(Analyser* ma, Stmt* s) {

ast/assert_stmt.c2

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,33 +22,42 @@ import string_buffer;
2222
public type AssertStmt struct @(opaque) {
2323
Stmt base;
2424
Expr* inner;
25+
Expr* call;
2526
}
2627

2728
public fn AssertStmt* AssertStmt.create(ast_context.Context* c,
28-
SrcLoc loc,
29-
Expr* inner)
29+
SrcLoc loc,
30+
Expr* inner,
31+
Expr* call)
3032
{
3133
AssertStmt* s = c.alloc(sizeof(AssertStmt));
3234
s.base.init(StmtKind.Assert, loc);
3335
s.inner = inner;
36+
s.call = call;
3437
#if AstStatistics
3538
Stats.addStmt(StmtKind.Assert, sizeof(AssertStmt));
3639
#endif
3740
return s;
3841
}
3942

4043
fn Stmt* AssertStmt.instantiate(AssertStmt* s, Instantiator* inst) {
41-
AssertStmt* s2 = AssertStmt.create(inst.c, s.base.loc, s.inner.instantiate(inst));
44+
AssertStmt* s2 = AssertStmt.create(inst.c, s.base.loc, s.inner.instantiate(inst),
45+
s.call ? s.call.instantiate(inst) : nil);
4246
return (Stmt*)s2;
4347
}
4448

4549
public fn Expr* AssertStmt.getInner(const AssertStmt* s) { return s.inner; }
4650

4751
public fn Expr** AssertStmt.getInner2(AssertStmt* s) { return &s.inner; }
4852

53+
public fn Expr* AssertStmt.getCall(const AssertStmt* s) { return s.call; }
54+
55+
public fn Expr** AssertStmt.getCall2(AssertStmt* s) { return &s.call; }
56+
4957
fn void AssertStmt.print(const AssertStmt* s, string_buffer.Buf* out, u32 indent) {
5058
s.base.printKind(out, indent);
5159
out.newline();
5260
s.inner.print(out, indent + 1);
61+
if (s.call) s.call.print(out, indent + 1);
5362
}
5463

ast/utils.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static_assert(80, sizeof(FunctionDecl));
3939
static_assert(8, sizeof(Stmt));
4040
static_assert(12, sizeof(GotoStmt));
4141
static_assert(24, sizeof(LabelStmt));
42-
static_assert(16, sizeof(AssertStmt));
42+
static_assert(24, sizeof(AssertStmt));
4343
static_assert(8, sizeof(DeclStmt));
4444
static_assert(16, sizeof(SwitchStmt));
4545
static_assert(24, sizeof(AsmStmt));

compiler/compiler.c2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ fn void Compiler.build(Compiler* c,
300300
c.astPool,
301301
c.builder,
302302
&c.kwinfo,
303-
target.getFeatures());
303+
target.getFeatures(),
304+
c.target.hasAsserts());
304305

305306
ast.initialize(c.context, c.astPool, c.targetInfo.intWidth / 8, color.useColor());
306307

generator/ast_visitor.c2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ fn void Visitor.handleStmt(Visitor* v, Stmt* s) {
216216
case Assert:
217217
AssertStmt* a = cast<AssertStmt*>(s);
218218
v.handleExpr(a.getInner());
219+
Expr* call = a.getCall();
220+
if (call) v.handleExpr(call);
219221
break;
220222
}
221223
}

generator/c/c2i_generator_stmt.c2

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -207,23 +207,10 @@ fn void Generator.emitStmt(Generator* gen, ast.Stmt* s, u32 indent, bool newline
207207
//gen.emitAsmStmt(cast<AsmStmt*>(s), indent);
208208
break;
209209
case Assert:
210-
#if 0
211-
// TODO: generate actual assert statement?
212210
AssertStmt* a = cast<AssertStmt*>(s);
213-
source_mgr.Location loc = gen.sm.getLocation(a.getLoc());
214-
const char* funcname = gen.cur_function.asDecl().getFullName();
215-
216-
out.add("(");
217-
Expr* inner = a.getInner();
218-
gen.emitExpr(out, inner);
219-
out.print(") || c2_assert(\"%s\", %d, \"%s\", \"", loc.filename, loc.line, funcname);
220-
// encode expression as a string
221-
string_buffer.Buf* str = string_buffer.create(128, false, 0);
222-
inner.printLiteral(str);
223-
out.encodeBytes(str.data(), str.size(), '"');
224-
str.free();
225-
out.add("\");\n");
226-
#endif
211+
out.add("assert(");
212+
gen.emitExpr(a.getInner());
213+
out.add(");\n");
227214
break;
228215
}
229216
}

generator/c/c_generator.c2

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,17 +1335,6 @@ const char[] C_defines =
13351335
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
13361336
```;
13371337

1338-
const char[] C2_assert =
1339-
```c
1340-
int dprintf(int fd, const char *format, ...);
1341-
void abort(void);
1342-
static int c2_assert(const char* filename, int line, const char* funcname, const char* condstr) {
1343-
dprintf(2, "%s:%d: function %s: Assertion failed: %s\n", filename, line, funcname, condstr);
1344-
abort();
1345-
return 0;
1346-
}
1347-
```;
1348-
13491338
const char[] C2_strswitch =
13501339
```c
13511340
static int c2_strswitch(const char* s1, const char* s2) {
@@ -1412,10 +1401,6 @@ fn void Generator.emit_external_header(Generator* gen, bool enable_asserts, cons
14121401
#endif
14131402
out.add("#define to_container(type, member, ptr) ((type*)((char*)(ptr) - offsetof(type, member)))\n\n");
14141403

1415-
if (enable_asserts) {
1416-
out.add(C2_assert);
1417-
}
1418-
14191404
// for switch(str):
14201405
// String format: strings are prefixed by a length byte and concatenated as a single character array.
14211406
// This minimizes memory use, cache misses and avoids extra symbols.

generator/c/c_generator_stmt.c2

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
module c_generator;
1717

1818
import ast local;
19-
import source_mgr;
2019
import string_buffer;
2120

2221
fn void Generator.emitVarDecl(Generator* gen, VarDecl* vd, string_buffer.Buf* out, bool emit_init, bool first) {
@@ -242,19 +241,14 @@ fn void Generator.emitStmt(Generator* gen, Stmt* s, u32 indent, bool newline) {
242241
if (!gen.enable_asserts) break;
243242

244243
AssertStmt* a = cast<AssertStmt*>(s);
245-
source_mgr.Location loc = gen.sm.locate(s.getLoc());
246-
const char* funcname = gen.cur_function.asDecl().getFullName();
247-
248-
out.add("(");
249-
Expr* inner = a.getInner();
250-
gen.emitExpr(out, inner);
251-
out.print(") || c2_assert(\"%s\", %d, \"%s\", \"", loc.filename, loc.line, funcname);
252-
// encode expression as a string
253-
string_buffer.Buf* str = string_buffer.create(128, false, 0);
254-
inner.printLiteral(str);
255-
out.encodeBytes(str.data(), str.size(), '"');
256-
str.free();
257-
out.add("\");\n");
244+
Expr* call = a.getCall();
245+
if (call) {
246+
out.add("(");
247+
gen.emitExpr(out, a.getInner());
248+
out.add(") || ");
249+
gen.emitExpr(out, call);
250+
out.add(";\n");
251+
}
258252
break;
259253
}
260254
}

libs/libc/c2_assert.c2i

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module c2_assert;
2+
3+
import stdio local;
4+
import stdlib local;
5+
6+
public fn i32 c2_assert_fail(const char* filename @(auto_file),
7+
u32 line @(auto_line),
8+
const char* funcname @(auto_func),
9+
const char* condstr)
10+
{
11+
dprintf(2, "%s:%d: function %s: Assertion failed: %s\n", filename, line, funcname, condstr);
12+
abort();
13+
return 0;
14+
}

libs/libc/manifest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ modules:
4040
- sys_utsname
4141
- uio
4242
- unistd
43-
43+
- c2_assert

0 commit comments

Comments
 (0)