diff --git a/CMakeLists.txt b/CMakeLists.txt index a263d53e0..d49f7e196 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,13 +210,13 @@ add_executable(c3c src/compiler/libraries.c src/compiler/linker.c src/compiler/llvm_codegen.c - src/compiler/llvm_codegen_c_abi_aarch64.c - src/compiler/llvm_codegen_c_abi.c - src/compiler/llvm_codegen_c_abi_riscv.c - src/compiler/llvm_codegen_c_abi_wasm.c - src/compiler/llvm_codegen_c_abi_win64.c - src/compiler/llvm_codegen_c_abi_x64.c - src/compiler/llvm_codegen_c_abi_x86.c + src/compiler/abi/c_abi_aarch64.c + src/compiler/abi/c_abi.c + src/compiler/abi/c_abi_riscv.c + src/compiler/abi/c_abi_wasm.c + src/compiler/abi/c_abi_win64.c + src/compiler/abi/c_abi_x64.c + src/compiler/abi/c_abi_x86.c src/compiler/llvm_codegen_debug_info.c src/compiler/llvm_codegen_expr.c src/compiler/llvm_codegen_function.c diff --git a/src/compiler/llvm_codegen_c_abi.c b/src/compiler/abi/c_abi.c similarity index 99% rename from src/compiler/llvm_codegen_c_abi.c rename to src/compiler/abi/c_abi.c index eddba7b71..5b20c363d 100644 --- a/src/compiler/llvm_codegen_c_abi.c +++ b/src/compiler/abi/c_abi.c @@ -2,7 +2,7 @@ // Use of this source code is governed by the GNU LGPLv3.0 license // a copy of which can be found in the LICENSE file. -#include "c_abi_internal.h" +#include "compiler/c_abi_internal.h" static ABIArgInfo *abi_arg_new(ABIKind kind) diff --git a/src/compiler/llvm_codegen_c_abi_aarch64.c b/src/compiler/abi/c_abi_aarch64.c similarity index 99% rename from src/compiler/llvm_codegen_c_abi_aarch64.c rename to src/compiler/abi/c_abi_aarch64.c index 89a56a290..565eb7d96 100644 --- a/src/compiler/llvm_codegen_c_abi_aarch64.c +++ b/src/compiler/abi/c_abi_aarch64.c @@ -2,7 +2,7 @@ // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. -#include "c_abi_internal.h" +#include "compiler/c_abi_internal.h" INLINE bool is_aarch64_illegal_vector(Type *type) { diff --git a/src/compiler/llvm_codegen_c_abi_riscv.c b/src/compiler/abi/c_abi_riscv.c similarity index 99% rename from src/compiler/llvm_codegen_c_abi_riscv.c rename to src/compiler/abi/c_abi_riscv.c index 6f3498c92..acf2956ff 100644 --- a/src/compiler/llvm_codegen_c_abi_riscv.c +++ b/src/compiler/abi/c_abi_riscv.c @@ -2,7 +2,7 @@ // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. -#include "c_abi_internal.h" +#include "compiler/c_abi_internal.h" static ABIArgInfo *riscv_coerce_and_expand_fpcc_struct(AbiType field1, unsigned field1_offset, AbiType field2, unsigned field2_offset) diff --git a/src/compiler/llvm_codegen_c_abi_wasm.c b/src/compiler/abi/c_abi_wasm.c similarity index 98% rename from src/compiler/llvm_codegen_c_abi_wasm.c rename to src/compiler/abi/c_abi_wasm.c index 5f42b0031..7f06dd2ad 100644 --- a/src/compiler/llvm_codegen_c_abi_wasm.c +++ b/src/compiler/abi/c_abi_wasm.c @@ -2,7 +2,7 @@ // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. -#include "c_abi_internal.h" +#include "compiler/c_abi_internal.h" static ABIArgInfo *wasm_classify_argument_type(Type *type) { diff --git a/src/compiler/llvm_codegen_c_abi_win64.c b/src/compiler/abi/c_abi_win64.c similarity index 99% rename from src/compiler/llvm_codegen_c_abi_win64.c rename to src/compiler/abi/c_abi_win64.c index bf95be8d5..8e7422b70 100644 --- a/src/compiler/llvm_codegen_c_abi_win64.c +++ b/src/compiler/abi/c_abi_win64.c @@ -2,7 +2,7 @@ // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. -#include "c_abi_internal.h" +#include "compiler/c_abi_internal.h" ABIArgInfo *win64_classify(Regs *regs, Type *type, bool is_return, bool is_vector) { diff --git a/src/compiler/llvm_codegen_c_abi_x64.c b/src/compiler/abi/c_abi_x64.c similarity index 99% rename from src/compiler/llvm_codegen_c_abi_x64.c rename to src/compiler/abi/c_abi_x64.c index 029c7d83d..3dd72641e 100644 --- a/src/compiler/llvm_codegen_c_abi_x64.c +++ b/src/compiler/abi/c_abi_x64.c @@ -2,7 +2,7 @@ // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. -#include "c_abi_internal.h" +#include "compiler/c_abi_internal.h" typedef enum { diff --git a/src/compiler/llvm_codegen_c_abi_x86.c b/src/compiler/abi/c_abi_x86.c similarity index 99% rename from src/compiler/llvm_codegen_c_abi_x86.c rename to src/compiler/abi/c_abi_x86.c index f5257d1af..a5b34900e 100644 --- a/src/compiler/llvm_codegen_c_abi_x86.c +++ b/src/compiler/abi/c_abi_x86.c @@ -2,7 +2,7 @@ // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. -#include "c_abi_internal.h" +#include "compiler/c_abi_internal.h" #define MIN_ABI_STACK_ALIGN 4 diff --git a/src/compiler/enums.h b/src/compiler/enums.h index e54fd57ee..a41af2aa9 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -768,6 +768,7 @@ typedef enum ATTRIBUTE_MAYDISCARD, ATTRIBUTE_NAKED, ATTRIBUTE_NODISCARD, + ATTRIBUTE_NOINIT, ATTRIBUTE_NOINLINE, ATTRIBUTE_NORETURN, ATTRIBUTE_OBFUSCATE, diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index bff771fa1..2af10472d 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -396,7 +396,7 @@ void llvm_emit_global_variable_init(GenContext *c, Decl *decl) } else { - init_value = llvm_get_zero(c, var_type); + init_value = decl->var.no_init ? llvm_get_undef(c, var_type) : llvm_get_zero(c, var_type); } diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 7f91cc8f8..49288fafb 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1441,6 +1441,7 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr, [ATTRIBUTE_MAYDISCARD] = ATTR_FUNC | ATTR_MACRO, [ATTRIBUTE_NAKED] = ATTR_FUNC, [ATTRIBUTE_NODISCARD] = ATTR_FUNC | ATTR_MACRO, + [ATTRIBUTE_NOINIT] = ATTR_GLOBAL | ATTR_LOCAL, [ATTRIBUTE_NOINLINE] = ATTR_FUNC | ATTR_CALL, [ATTRIBUTE_NORETURN] = ATTR_FUNC | ATTR_MACRO, [ATTRIBUTE_OBFUSCATE] = ATTR_ENUM, @@ -1635,6 +1636,9 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr, decl->func_decl.attr_noinline = true; decl->func_decl.attr_inline = false; break; + case ATTRIBUTE_NOINIT: + decl->var.no_init = true; + break; case ATTRIBUTE_NODISCARD: decl->func_decl.signature.attrs.nodiscard = true; break; diff --git a/src/compiler/symtab.c b/src/compiler/symtab.c index bf59f999a..924b25a3d 100644 --- a/src/compiler/symtab.c +++ b/src/compiler/symtab.c @@ -304,6 +304,7 @@ void symtab_init(uint32_t capacity) attribute_list[ATTRIBUTE_MAYDISCARD] = KW_DEF("@maydiscard"); attribute_list[ATTRIBUTE_NAKED] = KW_DEF("@naked"); attribute_list[ATTRIBUTE_NODISCARD] = KW_DEF("@nodiscard"); + attribute_list[ATTRIBUTE_NOINIT] = KW_DEF("@noinit"); attribute_list[ATTRIBUTE_NOINLINE] = KW_DEF("@noinline"); attribute_list[ATTRIBUTE_NORETURN] = KW_DEF("@noreturn"); attribute_list[ATTRIBUTE_OBFUSCATE] = KW_DEF("@obfuscate"); diff --git a/src/version.h b/src/version.h index 446cb6239..4001db580 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.55" \ No newline at end of file +#define COMPILER_VERSION "0.4.56" \ No newline at end of file diff --git a/test/test_suite/globals/global_no_init.c3t b/test/test_suite/globals/global_no_init.c3t new file mode 100644 index 000000000..8aecf5298 --- /dev/null +++ b/test/test_suite/globals/global_no_init.c3t @@ -0,0 +1,25 @@ +module test; + +struct Abc +{ + int[100] x; +} +int z @noinit; +Abc y @noinit; + +fn void main() +{ + z = y.x[0]; +} + +/* #expect: test.ll + +@test_z = local_unnamed_addr global i32 undef, align 4 +@test_y = local_unnamed_addr global %Abc undef, align 4 + +define void @test_main() #0 { +entry: + %0 = load i32, ptr @test_y, align 4 + store i32 %0, ptr @test_z, align 4 + ret void +} \ No newline at end of file diff --git a/test/test_suite/variables/var_init.c3t b/test/test_suite/variables/var_init.c3t new file mode 100644 index 000000000..0e0b6dae9 --- /dev/null +++ b/test/test_suite/variables/var_init.c3t @@ -0,0 +1,26 @@ +module test; + +struct Abc +{ + int[100] x; +} + + +fn void main() +{ + int z @noinit; + Abc y @noinit; + int x; + Abc w; +} + +/* #expect: test.ll + +entry: + %z = alloca i32, align 4 + %y = alloca %Abc, align 4 + %x = alloca i32, align 4 + %w = alloca %Abc, align 4 + store i32 0, ptr %x, align 4 + call void @llvm.memset.p0.i64(ptr align 4 %w, i8 0, i64 400, i1 false) + ret void