Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ast/ast_evaluator.c2
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ fn Value Evaluator.eval_call(Evaluator* caller, const CallExpr* c) {

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

if (num_args > elemsof(eval.args)) {
return Value.error("too many arguments in pure function evaluation");
Expand Down
9 changes: 9 additions & 0 deletions ast/var_decl.c2
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type VarDeclBits struct {
AutoAttr auto_attr : 2; // for parameters only
FormatAttr format_attr : 2; // for parameters only
u32 is_tlocal : 1; // local or global variables with thread local storage
u32 attr_noinit : 1;
}

public type BitFieldLayout struct {
Expand Down Expand Up @@ -315,6 +316,14 @@ public fn bool VarDecl.hasInitCall(const VarDecl* d) {
return d.base.varDeclBits.has_init_call;
}

public fn void VarDecl.setAttrNoInit(VarDecl* d) {
d.base.varDeclBits.attr_noinit = 1;
}

public fn bool VarDecl.hasAttrNoInit(const VarDecl* d) {
return d.base.varDeclBits.attr_noinit;
}

public fn void VarDecl.setAttrWeak(VarDecl* d) {
d.base.declBits.has_attr = 1;
d.base.varDeclBits.attr_weak = 1;
Expand Down
1 change: 1 addition & 0 deletions ast_utils/attr.c2
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public type AttrKind enum u8 (const char* const name, const AttrReq required_arg
AutoFunc : { "auto_func", NoArg }, // Var, function param only
Embed : { "embed", String }, // Var, globals only
Deprecated : { "deprecated", String }, // Func
NoInit : { "noinit", NoArg }, // Var
}

public type AttrValueKind enum u8 {
Expand Down
4 changes: 2 additions & 2 deletions ast_utils/string_buffer.c2
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public fn void Buf.stripTrailingSpaces(Buf* buf) {
}

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

public fn void Buf.vprintf(Buf* buf, const char* format, va_list args) {
char[4096] tmp;
char[4096] tmp /*@(noinit)*/;
// NOTE: no growing
i32 len = vsnprintf(tmp, elemsof(tmp), format, args);
assert(len < elemsof(tmp));
Expand Down
2 changes: 1 addition & 1 deletion ast_utils/value_type.c2
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ fn f64 fabs(f64 d) {
// string and trying to avoid using exponential notation
// TODO: should be in the C2 library as a type function f64.str()
public fn char *ftoa(char *dest, usize size, f64 d) {
char[32] buf;
char[32] buf /*@(noinit)*/;
usize pos = 0;

if (size < 2) {
Expand Down
3 changes: 3 additions & 0 deletions common/ast_builder.c2
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,9 @@ fn void Builder.actOnVarAttr(Builder* b, Decl* d, const Attr* a) {
if (!d.isPublic()) b.diags.error(a.loc, "weak declarations must be public");
vd.setAttrWeak();
break;
case NoInit:
vd.setAttrNoInit();
break;
default:
b.diags.error(a.loc, "attribute '%s' is not applicable to variables",
a.kind2name());
Expand Down
2 changes: 1 addition & 1 deletion common/file/file_utils.c2
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public fn const char* make_path3(char *buf, usize size, const char* dir, const c
// returns 0 on success, errno on failure
// create a directory path, OK if exists already
public fn i32 create_path(const char* path) {
char[file_utils.Max_path] tmp;
char[file_utils.Max_path] tmp /*@(noinit)*/;
char *p = tmp;
if (!*path) return 0;
*p++ = *path++;
Expand Down
2 changes: 1 addition & 1 deletion generator/c/c_generator_special.c2
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fn void Generator.createMakefile(Generator* gen,
out.print("CC?=%s\n", cc);

out.add("CFLAGS+=-Wall -Wextra -Wno-unused -Wno-switch\n");
out.add("CFLAGS+=-Wno-unused-parameter -Wno-missing-field-initializers -Wno-format-zero-length\n");
out.add("CFLAGS+=-Wno-unused-parameter -Wno-missing-field-initializers -Wno-missing-braces -Wno-format-zero-length\n");
out.add("CFLAGS+=-pipe -std=c99 -funsigned-char\n");
if (gen.fast_build)
out.add("CFLAGS+=-O0 -g\n");
Expand Down
4 changes: 4 additions & 0 deletions generator/c/c_generator_stmt.c2
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ fn void Generator.emitVarDecl(Generator* gen, VarDecl* vd, string_buffer.Buf* ou
out.add(" = ");
}
gen.emitExpr(out, ie);
} else {
if (!vd.hasAttrNoInit()) {
out.add(" = { 0 }");
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions parser/c2_parser.c2
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,10 @@ fn bool findName(const u32* names, u32 count, u32 name) {
// returns the number of attributes parsed and stored in Builder
fn u32 Parser.parseOptionalAttributes(Parser* p) {
if (p.tok.kind != At) return 0;
return p.parseAttributes();
}

fn u32 Parser.parseAttributes(Parser* p) {
p.consumeToken();

p.expectAndConsume(LParen);
Expand Down
14 changes: 12 additions & 2 deletions parser/c2_parser_stmt.c2
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import constants local;
import token local;
import src_loc local;
import string_list;
import string local;

import ctype;

Expand Down Expand Up @@ -531,7 +532,7 @@ fn Stmt* Parser.parseWhileStmt(Parser* p) {
}

fn Stmt* Parser.parseDeclStmt(Parser* p, bool checkSemi, bool allowLocal, bool isCondition) {
VarDecl*[MaxMultiDecl] decls;
VarDecl*[MaxMultiDecl] decls /*@(noinit)*/;
u32 num_decls = 0;
bool is_static = p.tok.kind == KW_static;
bool has_tlocal = (p.tok.kind == KW_tlocal);
Expand All @@ -556,6 +557,7 @@ fn Stmt* Parser.parseDeclStmt(Parser* p, bool checkSemi, bool allowLocal, bool i
p.consumeToken();

// TODO same as parseVarDecl()
bool has_noinit = false;
bool has_init_call = false;
need_semi = true;
Expr* initValue = nil;
Expand All @@ -570,7 +572,14 @@ fn Stmt* Parser.parseDeclStmt(Parser* p, bool checkSemi, bool allowLocal, bool i
need_semi = checkSemi && initValue.needsSemi();
break;
case At:
p.error("local variables cannot have attributes");
// check for noinit attribute
p.consumeToken();
p.expectAndConsume(Kind.LParen);
p.expectIdentifier();
if (strcmp(p.pool.idx2str(p.tok.name_idx), "noinit"))
p.error("local variables cannot have attributes");
has_noinit = true;
p.expectAndConsume(Kind.RParen);
break;
case Dot:
if (p.peekToken(1) == Identifier
Expand Down Expand Up @@ -600,6 +609,7 @@ fn Stmt* Parser.parseDeclStmt(Parser* p, bool checkSemi, bool allowLocal, bool i
}
VarDecl* vd = p.builder.actOnVarDecl(name, loc, &ref, assignLoc, initValue, is_static, has_init_call);
if (has_tlocal) vd.setTLocal();
if (has_noinit) vd.setAttrNoInit();
decls[num_decls++] = vd;
if (p.tok.kind != Comma)
break;
Expand Down
4 changes: 2 additions & 2 deletions parser/c2_tokenizer.c2
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ check_overflow:
}

fn void Tokenizer.lex_floating_point(Tokenizer* t, Token* result, const char* start) {
char[4096] buf;
char[128] buf /*@(noinit)*/;
const char* p = start;
usize pos = 0;
u8 seen_dot = 0;
Expand Down Expand Up @@ -941,7 +941,7 @@ too_large:
}

fn void Tokenizer.lex_floating_point_hex(Tokenizer* t, Token* result, const char* start) {
char[4096] buf;
char[128] buf /*@(noinit)*/;
const char* p = start;
usize pos = 0;
u8 seen_dot = 0;
Expand Down
2 changes: 1 addition & 1 deletion test/auto_args/struct_function_before_self.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static void test_Foo_test(const char* file, u32 line, test_Foo* f, void* p)

int main(void)
{
test_Foo f;
test_Foo f = { 0 };
test_Foo_test("file1.c2", 11, &f, NULL);
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion test/auto_args/struct_function_ok.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ static void test_Foo_test(test_Foo* f, const char* file, u32 line, void* p)

int main(void)
{
test_Foo f;
test_Foo f = { 0 };
test_Foo_test(&f, "file1.c2", 11, NULL);
test_Foo_test(&f, "file1.c2", 12, NULL);
return 0;
Expand Down
12 changes: 6 additions & 6 deletions test/c_generator/asm/gen_asm.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@ static void test_basic_asm(void);

static int test_add(int x, int y)
{
int result;
int result = { 0 };
__asm__ volatile ("add %[Rd], %[Rm], %[Rn]" : [Rd] "=r" (result) : [Rm] "r" (x), [Rn] "r" (y));
return result;
}

static void test_clobbers(void)
{
int from;
int to;
int count;
int from = { 0 };
int to = { 0 };
int count = { 0 };
__asm__ volatile ("movc3 %0, %1, %2"
:
: "g" (from), "g" (to), "g" (count)
Expand All @@ -67,8 +67,8 @@ static void test_clobbers(void)
static inline
u64 test_rdtsc(void)
{
u32 lo;
u32 hi;
u32 lo = { 0 };
u32 hi = { 0 };
__asm__ volatile ("rdtsc" : "=a" (lo), "=d" (hi));
u64 res = hi;
res <<= 32;
Expand Down
2 changes: 1 addition & 1 deletion test/c_generator/expr/prec_expr.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public fn i32 main(i32 argc, const char** argv) {

int main(int argc, const char** argv)
{
int a;
int a = { 0 };

a = (1 << 2) + 3;
a = ((1 ^ 2) | 3) & 4;
Expand Down
2 changes: 1 addition & 1 deletion test/c_generator/functions/inline/inline_prefix.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type Point struct {
static inline
void test1_myfunc(const test2_Point* p)
{
test2_Point points[3];
test2_Point points[3] = { 0 };
points[1] = *p;
}

4 changes: 2 additions & 2 deletions test/c_generator/functions/inline/inline_stmts.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ next:
static inline
int test1_test_fn(const char* format, ...)
{
const char* p;
const char* p = { 0 };
{
const char* q = format;
if (q) {
Expand All @@ -137,7 +137,7 @@ int test1_test_fn(const char* format, ...)
if (format) p = format;
else p = format;
{
const char* q;
const char* q = { 0 };
while ((q = format)) {
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/c_generator/functions/inline/lib_public_inline.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ typedef void (*test1_Handler)(int* _arg0);
static inline
int test1_test_fn(test1_Handler a, int** b)
{
int c[4];
int c[4] = { 0 };
a(*b);
return 123;
}
Expand Down
2 changes: 1 addition & 1 deletion test/c_generator/functions/inline/nonpublic_inline.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ void test1_test_fn(void)
{
test1_non_public();
test1_num++;
test1_Priv p;
test1_Priv p = { 0 };
test1_Handler h = test1_non_public;
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static test_B* test_C_getB(test_C* c)

static void test_test1(void)
{
test_C c;
test_C c = { 0 };
u32 n = test_A_run(test_B_getA(test_C_getB(&c)));
}

2 changes: 1 addition & 1 deletion test/c_generator/functions/struct_functions/local.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static void test_Type_init(test_Type* _arg0)

int main(void)
{
test_Type t;
test_Type t = { 0 };
test_Type_init(&t);
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion test/c_generator/functions/struct_functions/local_arg.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static void test_Type_init(test_Type* _arg0, int _arg1)

int main(void)
{
test_Type t;
test_Type t = { 0 };
test_Type_init(&t, 4);
return 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ static void test_Type_init(test_Type* _arg0)

int main(void)
{
test_Outer o;
test_Outer o = { 0 };
test_Type_init(&o.t);
return 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ struct test_Type_ {

int main(void)
{
test_Type t;
test_Type t = { 0 };
t.init(1);
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion test/c_generator/functions/struct_functions/local_ptr.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static void test_Type_init(test_Type* _arg0)

int main(void)
{
test_Type* t;
test_Type* t = { 0 };
test_Type_init(t);
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion test/c_generator/stmts/local_array_decl.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ static void test_func1(void);

static void test_func1(void)
{
int board2[20][20];
int board2[20][20] = { 0 };
}

2 changes: 1 addition & 1 deletion test/c_generator/stmts/while_stmt_expr.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int main(int argc, const char** argv)
}

{
int b;
int b = { 0 };
while ((b = 0)) {
}
}
Expand Down
2 changes: 1 addition & 1 deletion test/expr/assign_list.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ static test_Point test_new_point(int x, int y)
int main(void)
{
printf("p0={ %d, %d }\n", test_p0.x, test_p0.y);
test_Point p1;
test_Point p1 = { 0 };
p1 = (test_Point){ 3, 4 };
printf("p1={ %d, %d }\n", p1.x, p1.y);
test_print_point("p2", (test_Point){ 5, 6 });
Expand Down
2 changes: 1 addition & 1 deletion test/types/const/multi_const.c2t
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ int main(void)
const void* q = (const char* const*)p;
test_A* const cc = NULL;
q = (test_A* const*)&cc;
test_A aa[1];
test_A aa[1] = { 0 };
{
test_A* const b = aa;
if (b) return 0;
Expand Down
Loading
Loading