diff --git a/explorer/interpreter/interpreter.cpp b/explorer/interpreter/interpreter.cpp index 32f6a8fe7166..cabeb1e20040 100644 --- a/explorer/interpreter/interpreter.cpp +++ b/explorer/interpreter/interpreter.cpp @@ -1580,10 +1580,15 @@ auto Interpreter::StepExp() -> ErrorOr { case 0: *print_stream_ << llvm::formatv(format_string); break; - case 1: + case 1: { + if ((*args[1]).kind() == Value::Kind::UninitializedValue) { + return ProgramError(exp.source_loc()) + << "Printing uninitialized value"; + } *print_stream_ << llvm::formatv(format_string, cast(*args[1]).value()); break; + } default: CARBON_FATAL() << "Too many format args: " << num_format_args; } @@ -2114,6 +2119,17 @@ auto Interpreter::StepStmt() -> ErrorOr { if (definition.has_init()) { CARBON_ASSIGN_OR_RETURN( v, Convert(act.results()[0], dest_type, stmt.source_loc())); + } else if (dest_type->kind() == Value::Kind::StaticArrayType) { + const auto& array = cast(dest_type); + const auto& element_type = array->element_type(); + const auto size = array->size(); + + std::vector> elements; + elements.reserve(size); + for (size_t i = 0; i < size; i++) { + elements.push_back(arena_->New(&element_type)); + } + v = arena_->New(Value::Kind::TupleValue, elements); } else { v = arena_->New(p); } @@ -2258,6 +2274,7 @@ auto Interpreter::StepDeclaration() -> ErrorOr { switch (decl.kind()) { case DeclarationKind::VariableDeclaration: { const auto& var_decl = cast(decl); + const auto* var_type = &var_decl.binding().static_type(); if (var_decl.has_initializer()) { if (act.pos() == 0) { return todo_.Spawn( @@ -2270,6 +2287,21 @@ auto Interpreter::StepDeclaration() -> ErrorOr { todo_.Initialize(&var_decl.binding(), v); return todo_.FinishAction(); } + } else if (var_type->kind() == Value::Kind::StaticArrayType) { + const auto& array = cast(var_type); + const auto& element_type = array->element_type(); + const auto size = array->size(); + + std::vector> elements; + elements.reserve(size); + for (size_t i = 0; i < size; i++) { + elements.push_back(arena_->New(&element_type)); + } + + Nonnull v = + arena_->New(Value::Kind::TupleValue, elements); + todo_.Initialize(&var_decl.binding(), v); + return todo_.FinishAction(); } else { Nonnull v = arena_->New(&var_decl.binding().value()); diff --git a/explorer/testdata/array/fail_print_uninitalized_array_element.carbon b/explorer/testdata/array/fail_print_uninitalized_array_element.carbon new file mode 100644 index 000000000000..3af29155a5a3 --- /dev/null +++ b/explorer/testdata/array/fail_print_uninitalized_array_element.carbon @@ -0,0 +1,16 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{not} %{explorer-run} +// RUN: %{not} %{explorer-run-trace} + +package ExplorerTest impl; + +fn Main() -> i32 { + var my_array : [i32; 1]; + // CHECK:STDERR: RUNTIME ERROR: {{.*}}/explorer/testdata/array/fail_print_uninitalized_array_element.carbon:[[@LINE+1]]: Printing uninitialized value + Print("{0}", my_array[0]); + return 0; +} diff --git a/explorer/testdata/array/uninitialized_global_array_access.carbon b/explorer/testdata/array/uninitialized_global_array_access.carbon new file mode 100644 index 000000000000..296b1dfb4b3c --- /dev/null +++ b/explorer/testdata/array/uninitialized_global_array_access.carbon @@ -0,0 +1,19 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{explorer-run} +// RUN: %{explorer-run-trace} +// CHECK:STDOUT: 100 +// CHECK:STDOUT: result: 0 + +package ExplorerTest api; + +var my_array : [i32; 1]; + +fn Main() -> i32 { + my_array[0] = 100; + Print("{0}", my_array[0]); + return 0; +} diff --git a/explorer/testdata/array/uninitialized_local_array_access.carbon b/explorer/testdata/array/uninitialized_local_array_access.carbon new file mode 100644 index 000000000000..dd00a0253d47 --- /dev/null +++ b/explorer/testdata/array/uninitialized_local_array_access.carbon @@ -0,0 +1,18 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// RUN: %{explorer-run} +// RUN: %{explorer-run-trace} +// CHECK:STDOUT: 100 +// CHECK:STDOUT: result: 0 + +package ExplorerTest api; + +fn Main() -> i32 { + var my_array : [i32; 1]; + my_array[0] = 100; + Print("{0}", my_array[0]); + return 0; +}