diff --git a/src/llvm_ir_generator.cpp b/src/llvm_ir_generator.cpp index bd129636..acc17c6a 100644 --- a/src/llvm_ir_generator.cpp +++ b/src/llvm_ir_generator.cpp @@ -201,13 +201,15 @@ void LLVMIRGenerator::Visit(const ArrDeclNode& arr_decl) { auto arr_decl_type = dynamic_cast(arr_decl.type.get()); // This vector stores the initialize values for an array. std::vector arr_elems{}; - for (auto i = std::size_t{0}, e = arr_decl_type->len(); i < e; ++i) { - if (i < arr_decl.init_list.size()) { + for (auto i = std::size_t{0}, e = arr_decl_type->len(), + init_len = arr_decl.init_list.size(); + i < e; ++i) { + if (i < init_len) { auto& arr_init = arr_decl.init_list.at(i); arr_init->Accept(*this); } - if (i < arr_decl.init_list.size()) { + if (i < init_len) { auto init_val = val_recorder.ValOfPrevExpr(); if (arr_decl.is_global) { auto const_val = llvm::dyn_cast(init_val); @@ -222,7 +224,9 @@ void LLVMIRGenerator::Visit(const ArrDeclNode& arr_decl) { auto zero = llvm::ConstantInt::get(builder_.getInt32Ty(), 0, true); if (arr_decl.is_global) { arr_elems.push_back(zero); - } else { + } else if (!arr_decl.is_global && 0 < init_len) { + // If array is in local scope and its initialized values is not + // declared, then compiler will not set element values to 0. auto res_addr = builder_.CreateConstInBoundsGEP2_32( type, id_to_val.at(arr_decl.id), 0, i); builder_.CreateStore(zero, res_addr); diff --git a/src/qbe_ir_generator.cpp b/src/qbe_ir_generator.cpp index 61922a45..df7d5a8b 100644 --- a/src/qbe_ir_generator.cpp +++ b/src/qbe_ir_generator.cpp @@ -257,8 +257,14 @@ void QbeIrGenerator::Visit(const ArrDeclNode& arr_decl) { arr_decl.type->size()); id_to_num[arr_decl.id] = base_addr_num; - for (auto i = std::size_t{0}, e = arr_type->len(); i < e; ++i) { - if (i < arr_decl.init_list.size()) { + // NOTE: Compiler will not set elements to 0 if `init_len` is 0. + // 6.7.9 Initialization + // 10. If an object that has automatic storage duration is not initialized + // explicitly, its value is indeterminate. + for (auto i = std::size_t{0}, e = arr_type->len(), + init_len = arr_decl.init_list.size(); + i < e && 0 < init_len; ++i) { + if (i < init_len) { auto& arr_init = arr_decl.init_list.at(i); arr_init->Accept(*this); } @@ -271,7 +277,7 @@ void QbeIrGenerator::Visit(const ArrDeclNode& arr_decl) { WriteInstr_("{} =l add {}, {}", FuncScopeTemp{res_addr_num}, FuncScopeTemp{base_addr_num}, FuncScopeTemp{offset}); - if (i < arr_decl.init_list.size()) { + if (i < init_len) { int init_val_num = num_recorder.NumOfPrevExpr(); WriteInstr_("storew {}, {}", FuncScopeTemp{init_val_num}, FuncScopeTemp{res_addr_num}); diff --git a/test/codegen/array.c b/test/codegen/array.c index 3e6b375a..4c90c991 100644 --- a/test/codegen/array.c +++ b/test/codegen/array.c @@ -22,5 +22,6 @@ int main() { __builtin_print(e[1]); __builtin_print(e[2]); + int f[2]; return 0; }