Skip to content

Commit 66c54d1

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 9817258 commit 66c54d1

33 files changed

Lines changed: 95 additions & 64 deletions

ast/ast_evaluator.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ fn Value Evaluator.eval_call(Evaluator* caller, const CallExpr* c) {
353353

354354
// Create a new stack frame and link it to the caller's
355355
// TODO: handle Stack frames as separate allocated objects or fragments of a stack area
356-
Evaluator eval;
356+
Evaluator eval /*@(noinit)*/;
357357

358358
if (num_args > elemsof(eval.args)) {
359359
return Value.error("too many arguments in pure function evaluation");

ast/value.c2

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

829829
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 addr_used : 1;
5858
AutoAttr auto_attr : 2; // for parameters only
5959
FormatAttr format_attr : 2; // for parameters only
60+
u32 attr_noinit : 1;
6061
}
6162

6263
public type BitFieldLayout struct {
@@ -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] attrKind_names = {
@@ -71,6 +72,7 @@ const char*[AttrKind] attrKind_names = {
7172
"auto_func",
7273
"embed",
7374
"deprecated",
75+
"noinit",
7476
}
7577

7678
public type AttrValueKind enum u8 {
@@ -148,6 +150,7 @@ const AttrReq[AttrKind] Required_arg = {
148150
[AutoFunc] = NoArg,
149151
[Embed] = String,
150152
[Deprecated] = String,
153+
[NoInit] = NoArg,
151154
}
152155

153156
public type AttrReq enum u8 {

ast_utils/string_buffer.c2

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

171171
public fn void Buf.print(Buf* buf, const char* format @(printf_format), ...) {
172-
char[4096] tmp;
172+
char[4096] tmp /*@(noinit)*/;
173173
// NOTE: no growing
174174
va_list args;
175175
va_start(args, format);
@@ -180,7 +180,7 @@ public fn void Buf.print(Buf* buf, const char* format @(printf_format), ...) {
180180
}
181181

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

common/ast_builder.c2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,9 @@ fn void Builder.actOnVarAttr(Builder* b, Decl* d, const Attr* a) {
511511
case Embed:
512512
b.storeAttr(d, a);
513513
break;
514+
case NoInit:
515+
vd.setAttrNoInit();
516+
break;
514517
default:
515518
b.diags.error(a.loc, "attribute '%s' is not applicable to variables",
516519
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
@@ -1297,8 +1297,7 @@ public fn void generate(string_pool.Pool* astPool,
12971297
return;
12981298
}
12991299

1300-
Generator gen;
1301-
gen.init(astPool, target, kind, output_dir, dir, diags, sm, build_info, mainFunc);
1300+
Generator gen.init(astPool, target, kind, output_dir, dir, diags, sm, build_info, mainFunc);
13021301
gen.auxPool = auxPool;
13031302
gen.enable_asserts = enable_asserts;
13041303
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
@@ -60,7 +60,7 @@ fn void Generator.createMakefile(Generator* gen,
6060
out.print("CC=%s\n", cc);
6161

6262
out.add("CFLAGS=-Wall -Wextra -Wno-unused -Wno-switch\n");
63-
out.add("CFLAGS+=-Wno-unused-parameter -Wno-missing-field-initializers -Wno-format-zero-length\n");
63+
out.add("CFLAGS+=-Wno-unused-parameter -Wno-missing-field-initializers -Wno-missing-braces -Wno-format-zero-length\n");
6464
out.add("CFLAGS+=-pipe -std=c99 -funsigned-char\n");
6565
if (gen.fast_build)
6666
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)