Skip to content

Commit 3307c8b

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 08eccd0 commit 3307c8b

34 files changed

Lines changed: 96 additions & 65 deletions

ast/ast_evaluator.c2

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

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

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

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));

ast_utils/value_type.c2

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

830830
if (size < 2) {

common/ast_builder.c2

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

1312-
Generator gen;
1313-
gen.init(astPool, target, kind, output_dir, dir, diags, sm, build_info, mainFunc);
1312+
Generator gen.init(astPool, target, kind, output_dir, dir, diags, sm, build_info, mainFunc);
13141313
gen.auxPool = auxPool;
13151314
gen.enable_asserts = enable_asserts;
13161315
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
@@ -39,6 +39,10 @@ fn void Generator.emitVarDecl(Generator* gen, VarDecl* vd, string_buffer.Buf* ou
3939
out.add(" = ");
4040
}
4141
gen.emitExpr(out, ie);
42+
} else {
43+
if (!vd.hasAttrNoInit()) {
44+
out.add(" = { 0 }");
45+
}
4246
}
4347
}
4448

0 commit comments

Comments
 (0)