Skip to content

Commit e6a49fd

Browse files
committed
Compiler: force zero initialization of local variables
* make all local variables zero-initialized except if tagged as `@(noinit)` * update tests
1 parent 7b17e77 commit e6a49fd

33 files changed

+99
-68
lines changed

ast/ast_evaluator.c2

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,17 +284,17 @@ fn Value Evaluator.eval_call(Evaluator* caller, const CallExpr* c) {
284284

285285
// Create a new stack frame and link it to the caller's
286286
// TODO: handle Stack frames as separate allocated objects
287-
Evaluator eval;
288-
289-
if (num_args > elemsof(eval.args)) {
290-
return Value.error("too many arguments in pure function evaluation");
291-
}
287+
Evaluator eval /*@(noinit)*/;
292288
eval.prev = caller;
293289
eval.fd = fd;
294290
eval.num_args = num_args;
295291
eval.depth = caller.depth + 1;
296292
eval.complexity = caller.complexity + 1;
297293

294+
if (num_args > elemsof(eval.args)) {
295+
return Value.error("too many arguments in pure function evaluation");
296+
}
297+
298298
//VarDecl** params = fd.getParams();
299299

300300
for (u32 i = 0; i < num_args; i++) {

ast/value.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -799,7 +799,7 @@ fn f64 fabs(f64 d) {
799799
// string and trying to avoid using exponential notation
800800
// TODO: should be in the C2 library as a type function f64.str()
801801
public fn char *ftoa(char *dest, usize size, f64 d) {
802-
char[32] buf;
802+
char[32] buf /*@(noinit)*/;
803803
usize pos = 0;
804804

805805
if (size < 2) {

ast/var_decl.c2

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type VarDeclBits struct {
5757
u32 has_init_call : 1; // local variables only
5858
u32 attr_weak : 1; // globals only
5959
u32 addr_used : 1;
60+
u32 attr_noinit : 1;
6061
u32 auto_attr : 2; // AutoAttr, for parameters only
6162
u32 format_attr : 2; // FormatAttr, for parameters only
6263
}
@@ -307,6 +308,14 @@ public fn bool VarDecl.hasInitCall(const VarDecl* d) {
307308
return d.base.varDeclBits.has_init_call;
308309
}
309310

311+
public fn void VarDecl.setAttrNoInit(VarDecl* d) {
312+
d.base.varDeclBits.attr_noinit = 1;
313+
}
314+
315+
public fn bool VarDecl.hasAttrNoInit(const VarDecl* d) {
316+
return d.base.varDeclBits.attr_noinit;
317+
}
318+
310319
public fn void VarDecl.setAttrWeak(VarDecl* d) {
311320
d.base.varDeclBits.attr_weak = 1;
312321
}

ast_utils/attr.c2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public type AttrKind enum u8 {
4444
AutoFunc, // Var, function param only
4545
Embed, // Var, globals only
4646
Deprecated, // Func
47+
NoInit, // Var
4748
}
4849

4950
const char*[] attrKind_names = {
@@ -71,6 +72,7 @@ const char*[] attrKind_names = {
7172
"auto_func",
7273
"embed",
7374
"deprecated",
75+
"noinit",
7476
}
7577

7678
static_assert(elemsof(AttrKind), elemsof(attrKind_names));
@@ -150,6 +152,7 @@ const AttrReq[] Required_arg = {
150152
[AttrKind.AutoFunc] = AttrReq.NoArg,
151153
[AttrKind.Embed] = AttrReq.String,
152154
[AttrKind.Deprecated] = AttrReq.String,
155+
[AttrKind.NoInit] = AttrReq.NoArg,
153156
}
154157
static_assert(elemsof(AttrKind), elemsof(Required_arg));
155158

ast_utils/string_buffer.c2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public fn void Buf.stripTrailingSpaces(Buf* buf) {
167167
}
168168

169169
public fn void Buf.print(Buf* buf, const char* format @(printf_format), ...) {
170-
char[4096] tmp;
170+
char[4096] tmp /*@(noinit)*/;
171171
// NOTE: no growing
172172
va_list args;
173173
va_start(args, format);
@@ -178,7 +178,7 @@ public fn void Buf.print(Buf* buf, const char* format @(printf_format), ...) {
178178
}
179179

180180
public fn void Buf.vprintf(Buf* buf, const char* format, va_list args) {
181-
char[4096] tmp;
181+
char[4096] tmp /*@(noinit)*/;
182182
// NOTE: no growing
183183
i32 len = vsnprintf(tmp, sizeof(tmp), format, args);
184184
assert(len < sizeof(tmp));

common/ast_builder.c2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,9 @@ fn void Builder.actOnVarAttr(Builder* b, Decl* d, const Attr* a) {
505505
case Embed:
506506
b.storeAttr(d, a);
507507
break;
508+
case NoInit:
509+
vd.setAttrNoInit();
510+
break;
508511
default:
509512
b.diags.error(a.loc, "attribute '%s' is not applicable to variables",
510513
a.kind2name());

common/file/file_utils.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public fn const char* make_path3(char *buf, usize size, const char* dir, const c
116116
// returns 0 on success, errno on failure
117117
// create a directory path, OK if exists already
118118
public fn i32 create_path(const char* path) {
119-
char[file_utils.Max_path] tmp;
119+
char[file_utils.Max_path] tmp /*@(noinit)*/;
120120
char *p = tmp;
121121
if (!*path) return 0;
122122
*p++ = *path++;

generator/c/c_generator.c2

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,8 +1303,7 @@ public fn void generate(string_pool.Pool* astPool,
13031303
return;
13041304
}
13051305

1306-
Generator gen;
1307-
gen.init(astPool, target, kind, output_dir, dir, diags, sm, build_info, mainFunc);
1306+
Generator gen.init(astPool, target, kind, output_dir, dir, diags, sm, build_info, mainFunc);
13081307
gen.auxPool = auxPool;
13091308
gen.enable_asserts = enable_asserts;
13101309
gen.fast_build = fast_build;

generator/c/c_generator_special.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ fn void Generator.createMakefile(Generator* gen,
6262
out.print("CC=%s\n", cc);
6363

6464
out.add("CFLAGS=-Wall -Wextra -Wno-unused -Wno-switch\n");
65-
out.add("CFLAGS+=-Wno-unused-parameter -Wno-missing-field-initializers -Wno-format-zero-length\n");
65+
out.add("CFLAGS+=-Wno-unused-parameter -Wno-missing-field-initializers -Wno-missing-braces -Wno-format-zero-length\n");
6666
out.add("CFLAGS+=-pipe -std=c99 -funsigned-char\n");
6767
if (gen.fast_build)
6868
out.add("CFLAGS+=-O0 -g\n");

generator/c/c_generator_stmt.c2

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ fn void Generator.emitVarDecl(Generator* gen, VarDecl* vd, string_buffer.Buf* ou
4040
out.add(" = ");
4141
}
4242
gen.emitExpr(out, ie);
43+
} else {
44+
if (!vd.hasAttrNoInit()) {
45+
out.add(" = { 0 }");
46+
}
4347
}
4448
}
4549

0 commit comments

Comments
 (0)