Skip to content

Commit 3fd9fc8

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 76fb5a7 commit 3fd9fc8

File tree

13 files changed

+82
-40
lines changed

13 files changed

+82
-40
lines changed

analyser/module_analyser_stmt.c2

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

438438
Expr* inner = a.getInner();
439439
ma.checker.check(builtins[BuiltinKind.Bool], qt, a.getInner2(), inner.getLoc());
440+
441+
if (a.getCall()) {
442+
qt = ma.analyseExpr(a.getCall2(), true, RHS);
443+
if (qt.isInvalid()) return;
444+
}
440445
}
441446

442447
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,32 +22,41 @@ 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-
return (Stmt*)AssertStmt.create(inst.c, s.base.loc, s.inner.instantiate(inst));
44+
return (Stmt*)AssertStmt.create(inst.c, s.base.loc, s.inner.instantiate(inst),
45+
s.call ? s.call.instantiate(inst) : nil);
4246
}
4347

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

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

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

ast/utils.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static_assert(80, sizeof(FunctionDecl));
4141
static_assert(8, sizeof(Stmt));
4242
static_assert(12, sizeof(GotoStmt));
4343
static_assert(24, sizeof(LabelStmt));
44-
static_assert(16, sizeof(AssertStmt));
44+
static_assert(24, sizeof(AssertStmt));
4545
static_assert(8, sizeof(DeclStmt));
4646
static_assert(16, sizeof(SwitchStmt));
4747
static_assert(24, sizeof(AsmStmt));

compiler/compiler.c2

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,8 @@ fn void Compiler.build(Compiler* c,
314314
c.astPool,
315315
c.builder,
316316
&c.kwinfo,
317-
target.getFeatures());
317+
target.getFeatures(),
318+
c.target.hasAsserts());
318319

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

generator/ast_visitor.c2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ fn void Visitor.handleStmt(Visitor* v, Stmt* s) {
218218
case Assert:
219219
AssertStmt* a = (AssertStmt*)s;
220220
v.handleExpr(a.getInner());
221+
Expr* call = a.getCall();
222+
if (call) v.handleExpr(call);
221223
break;
222224
}
223225
}

generator/c/c_generator.c2

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

1436-
const char[] C2_assert =
1437-
```c
1438-
int dprintf(int fd, const char *format, ...);
1439-
void abort(void);
1440-
static int c2_assert(const char* filename, int line, const char* funcname, const char* condstr) {
1441-
dprintf(2, "%s:%d: function %s: Assertion failed: %s\n", filename, line, funcname, condstr);
1442-
abort();
1443-
return 0;
1444-
}
1445-
```;
1446-
14471436
const char[] C2_strswitch =
14481437
```c
14491438
static int c2_strswitch(const char* s1, const char* s2) {
@@ -1510,10 +1499,6 @@ fn void Generator.emit_external_header(Generator* gen, bool enable_asserts, cons
15101499
#endif
15111500
out.add("#define to_container(type, member, ptr) ((type*)((char*)(ptr) - offsetof(type, member)))\n\n");
15121501

1513-
if (enable_asserts) {
1514-
out.add(C2_assert);
1515-
}
1516-
15171502
// for switch(str):
15181503
// String format: strings are prefixed by a length byte and concatenated as a single character array.
15191504
// This minimizes memory use, cache misses and avoids extra symbols.

generator/c/c_generator_stmt.c2

Lines changed: 5 additions & 13 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) {
@@ -240,19 +239,12 @@ fn void Generator.emitStmt(Generator* gen, Stmt* s, u32 indent, bool newline) {
240239
if (!gen.enable_asserts) out.print(";//assert");
241240
AssertStmt* a = (AssertStmt*)s;
242241
out.add1('(');
243-
Expr* inner = a.getInner();
244-
gen.emitExpr(out, inner);
242+
gen.emitExpr(out, a.getInner());
245243
out.add1(')');
246-
if (gen.enable_asserts) {
247-
source_mgr.Location loc = gen.sm.locate(s.getLoc());
248-
const char* funcname = gen.cur_function.asDecl().getFullName();
249-
out.print(" || c2_assert(\"%s\", %d, \"%s\", \"", loc.filename, loc.line, funcname);
250-
// encode expression as a string
251-
string_buffer.Buf* str = string_buffer.create(128, false, 0);
252-
inner.printLiteral(str);
253-
out.encodeBytes(str.data(), str.size(), '"');
254-
str.free();
255-
out.add("\")");
244+
Expr* call = a.getCall();
245+
if (call) {
246+
out.add(" || ");
247+
gen.emitExpr(out, call);
256248
}
257249
out.add(";\n");
258250
break;

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

parser/ast_builder.c2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -893,8 +893,8 @@ public fn SwitchCase* Builder.actOnCase(Builder* b,
893893
conds, num_conds, stmts, num_stmts);
894894
}
895895

896-
public fn Stmt* Builder.actOnAssertStmt(Builder* b, SrcLoc loc, Expr* inner) {
897-
return (Stmt*)AssertStmt.create(b.context, loc, inner);
896+
public fn Stmt* Builder.actOnAssertStmt(Builder* b, SrcLoc loc, Expr* inner, Expr* call) {
897+
return (Stmt*)AssertStmt.create(b.context, loc, inner, call);
898898
}
899899

900900
public fn Stmt* Builder.actOnBreakStmt(Builder* b, SrcLoc loc) {

0 commit comments

Comments
 (0)