From d7978deb3a34045d7bb1c70d8fe42883ed739397 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Thu, 13 Apr 2023 12:53:34 -0700 Subject: [PATCH] Start doing more validation of intrinsics: assert, new, delete, rand (#2766) This is adding more validation of intrinsics. It addresses a bug in rand where CHECK-fails would occur for bad range inputs, instead of a runtime error. I'm also addressing what I think was an int32 range issue in the handling by running the generator with int64. --- explorer/interpreter/interpreter.cpp | 23 +++++++++++++----- explorer/interpreter/type_checker.cpp | 2 +- explorer/testdata/assert/assert.carbon | 15 ++++++++++++ explorer/testdata/assert/convert.carbon | 22 +++++++++++++++++ explorer/testdata/assert/fail_assert.carbon | 1 - explorer/testdata/assert/fail_convert.carbon | 7 ++---- .../assert/fail_intrinsic_bool_type.carbon | 22 +++++++++++++++++ .../assert/fail_intrinsic_no_args.carbon | 22 +++++++++++++++++ .../assert/fail_intrinsic_no_convert.carbon | 24 +++++++++++++++++++ .../assert/fail_intrinsic_str_type.carbon | 24 +++++++++++++++++++ .../pointer/fail_delete_uninit.carbon | 16 +++++++++++++ .../fail_intrinsic_delete_no_args.carbon | 15 ++++++++++++ .../pointer/fail_intrinsic_delete_type.carbon | 18 ++++++++++++++ .../pointer/fail_intrinsic_new_no_args.carbon | 15 ++++++++++++ .../pointer/new_and_delete_class.carbon | 23 ++++++++++++++++++ .../testdata/pointer/new_and_delete_fn.carbon | 21 ++++++++++++++++ .../testdata/random/fail_empty_range.carbon | 15 ++++++++++++ .../random/fail_intrinsic_no_args.carbon | 15 ++++++++++++ .../random/fail_intrinsic_type0.carbon | 17 +++++++++++++ .../random/fail_intrinsic_type1.carbon | 17 +++++++++++++ .../testdata/random/fail_reverse_range.carbon | 15 ++++++++++++ explorer/testdata/random/max_range.carbon | 19 +++++++++++++++ explorer/testdata/random/random.carbon | 12 ++++------ 23 files changed, 360 insertions(+), 20 deletions(-) create mode 100644 explorer/testdata/assert/assert.carbon create mode 100644 explorer/testdata/assert/convert.carbon create mode 100644 explorer/testdata/assert/fail_intrinsic_bool_type.carbon create mode 100644 explorer/testdata/assert/fail_intrinsic_no_args.carbon create mode 100644 explorer/testdata/assert/fail_intrinsic_no_convert.carbon create mode 100644 explorer/testdata/assert/fail_intrinsic_str_type.carbon create mode 100644 explorer/testdata/pointer/fail_delete_uninit.carbon create mode 100644 explorer/testdata/pointer/fail_intrinsic_delete_no_args.carbon create mode 100644 explorer/testdata/pointer/fail_intrinsic_delete_type.carbon create mode 100644 explorer/testdata/pointer/fail_intrinsic_new_no_args.carbon create mode 100644 explorer/testdata/pointer/new_and_delete_class.carbon create mode 100644 explorer/testdata/pointer/new_and_delete_fn.carbon create mode 100644 explorer/testdata/random/fail_empty_range.carbon create mode 100644 explorer/testdata/random/fail_intrinsic_no_args.carbon create mode 100644 explorer/testdata/random/fail_intrinsic_type0.carbon create mode 100644 explorer/testdata/random/fail_intrinsic_type1.carbon create mode 100644 explorer/testdata/random/fail_reverse_range.carbon create mode 100644 explorer/testdata/random/max_range.carbon diff --git a/explorer/interpreter/interpreter.cpp b/explorer/interpreter/interpreter.cpp index 53f1e0caf714..29f94d9554e9 100644 --- a/explorer/interpreter/interpreter.cpp +++ b/explorer/interpreter/interpreter.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -40,8 +41,6 @@ using llvm::isa; namespace Carbon { -static std::mt19937 generator(12); - // Constructs an ActionStack suitable for the specified phase. static auto MakeTodo(Phase phase, Nonnull heap) -> ActionStack { switch (phase) { @@ -1593,12 +1592,24 @@ auto Interpreter::StepExp() -> ErrorOr { } case IntrinsicExpression::Intrinsic::Rand: { CARBON_CHECK(args.size() == 2); - const auto& low = cast(*args[0]).value(); - const auto& high = cast(*args[1]).value(); - CARBON_CHECK(high > low); + const int64_t low = cast(*args[0]).value(); + const int64_t high = cast(*args[1]).value(); + if (low >= high) { + return ProgramError(exp.source_loc()) + << "Rand inputs must be ordered for a non-empty range: " + << low << " must be less than " << high; + } + // Use 64-bit to handle large ranges where `high - low` might exceed + // int32_t maximums. + static std::mt19937_64 generator(12); + const int64_t range = high - low; // We avoid using std::uniform_int_distribution because it's not // reproducible across builds/platforms. - int r = (generator() % (high - low)) + low; + int64_t r = (generator() % range) + low; + CARBON_CHECK(r >= std::numeric_limits::min() && + r <= std::numeric_limits::max()) + << "Non-int32 result: " << r; + CARBON_CHECK(r >= low && r <= high) << "Out-of-range result: " << r; return todo_.FinishAction(arena_->New(r)); } case IntrinsicExpression::Intrinsic::ImplicitAs: { diff --git a/explorer/interpreter/type_checker.cpp b/explorer/interpreter/type_checker.cpp index 97ebed3dcbaf..a8728cf86b89 100644 --- a/explorer/interpreter/type_checker.cpp +++ b/explorer/interpreter/type_checker.cpp @@ -3666,7 +3666,7 @@ auto TypeChecker::TypeCheckExp(Nonnull e, case IntrinsicExpression::Intrinsic::Dealloc: { if (args.size() != 1) { return ProgramError(e->source_loc()) - << "__intrinsic_new takes 1 argument"; + << "__intrinsic_delete takes 1 argument"; } const auto* arg_type = &args[0]->static_type(); CARBON_RETURN_IF_ERROR( diff --git a/explorer/testdata/assert/assert.carbon b/explorer/testdata/assert/assert.carbon new file mode 100644 index 000000000000..689eb46aa512 --- /dev/null +++ b/explorer/testdata/assert/assert.carbon @@ -0,0 +1,15 @@ +// 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: result: 0 + +package ExplorerTest api; + +fn Main() -> i32 { + Assert(true, "HALLO WELT"); + return 0; +} diff --git a/explorer/testdata/assert/convert.carbon b/explorer/testdata/assert/convert.carbon new file mode 100644 index 000000000000..c3a8458465e7 --- /dev/null +++ b/explorer/testdata/assert/convert.carbon @@ -0,0 +1,22 @@ +// 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: result: 0 + +package ExplorerTest api; + +class ConvertTo(T:! type) { + var v: T; + impl as ImplicitAs(T) { + fn Convert[self: Self]() -> T { return self.v; } + } +} + +fn Main() -> i32 { + Assert({.v = true} as ConvertTo(bool), {.v = "Pass"} as ConvertTo(String)); + return 0; +} diff --git a/explorer/testdata/assert/fail_assert.carbon b/explorer/testdata/assert/fail_assert.carbon index cf81ff9aec2e..50976f902c6d 100644 --- a/explorer/testdata/assert/fail_assert.carbon +++ b/explorer/testdata/assert/fail_assert.carbon @@ -10,7 +10,6 @@ package ExplorerTest api; fn Main() -> i32 { - Assert(true, "HALLO WELT"); Assert(false, "HALLO WELT"); return 0; } diff --git a/explorer/testdata/assert/fail_convert.carbon b/explorer/testdata/assert/fail_convert.carbon index 53ee9099be93..5ee3c88fa9ec 100644 --- a/explorer/testdata/assert/fail_convert.carbon +++ b/explorer/testdata/assert/fail_convert.carbon @@ -5,6 +5,7 @@ // AUTOUPDATE // RUN: %{not} %{explorer-run} // RUN: %{not} %{explorer-run-trace} +// CHECK:STDERR: RUNTIME ERROR: {{.*}}/explorer/data/prelude.carbon:{{.*}}: "Fail" package ExplorerTest api; @@ -16,10 +17,6 @@ class ConvertTo(T:! type) { } fn Main() -> i32 { - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/assert/fail_convert.carbon:[[@LINE+3]]: type error in __intrinsic_assert argument 0 - // CHECK:STDERR: expected: bool - // CHECK:STDERR: actual: class ConvertTo(T = bool) - __intrinsic_assert({.v = true} as ConvertTo(bool), {.v = "Pass"} as ConvertTo(String)); - __intrinsic_assert({.v = false} as ConvertTo(bool), {.v = "Fail"} as ConvertTo(String)); + Assert({.v = false} as ConvertTo(bool), {.v = "Fail"} as ConvertTo(String)); return 0; } diff --git a/explorer/testdata/assert/fail_intrinsic_bool_type.carbon b/explorer/testdata/assert/fail_intrinsic_bool_type.carbon new file mode 100644 index 000000000000..0ec61ba97c34 --- /dev/null +++ b/explorer/testdata/assert/fail_intrinsic_bool_type.carbon @@ -0,0 +1,22 @@ +// 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 api; + +class ConvertTo(T:! type) { + var v: T; + impl as ImplicitAs(T) { + fn Convert[self: Self]() -> T { return self.v; } + } +} + +fn Main() -> i32 { + // CHECK:STDERR: SYNTAX ERROR: {{.*}}/explorer/testdata/assert/fail_intrinsic_bool_type.carbon:[[@LINE+1]]: syntax error, unexpected COMMA + __intrinsic_assert(, "unused"); + return 0; +} diff --git a/explorer/testdata/assert/fail_intrinsic_no_args.carbon b/explorer/testdata/assert/fail_intrinsic_no_args.carbon new file mode 100644 index 000000000000..c8a8b62a27c8 --- /dev/null +++ b/explorer/testdata/assert/fail_intrinsic_no_args.carbon @@ -0,0 +1,22 @@ +// 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 api; + +class ConvertTo(T:! type) { + var v: T; + impl as ImplicitAs(T) { + fn Convert[self: Self]() -> T { return self.v; } + } +} + +fn Main() -> i32 { + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/assert/fail_intrinsic_no_args.carbon:[[@LINE+1]]: __intrinsic_assert takes 2 arguments + __intrinsic_assert(); + return 0; +} diff --git a/explorer/testdata/assert/fail_intrinsic_no_convert.carbon b/explorer/testdata/assert/fail_intrinsic_no_convert.carbon new file mode 100644 index 000000000000..b089a5a15063 --- /dev/null +++ b/explorer/testdata/assert/fail_intrinsic_no_convert.carbon @@ -0,0 +1,24 @@ +// 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 api; + +class ConvertTo(T:! type) { + var v: T; + impl as ImplicitAs(T) { + fn Convert[self: Self]() -> T { return self.v; } + } +} + +fn Main() -> i32 { + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/assert/fail_intrinsic_no_convert.carbon:[[@LINE+3]]: type error in __intrinsic_assert argument 0 + // CHECK:STDERR: expected: bool + // CHECK:STDERR: actual: class ConvertTo(T = bool) + __intrinsic_assert({.v = true} as ConvertTo(bool), {.v = "Pass"} as ConvertTo(String)); + return 0; +} diff --git a/explorer/testdata/assert/fail_intrinsic_str_type.carbon b/explorer/testdata/assert/fail_intrinsic_str_type.carbon new file mode 100644 index 000000000000..de012f444138 --- /dev/null +++ b/explorer/testdata/assert/fail_intrinsic_str_type.carbon @@ -0,0 +1,24 @@ +// 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 api; + +class ConvertTo(T:! type) { + var v: T; + impl as ImplicitAs(T) { + fn Convert[self: Self]() -> T { return self.v; } + } +} + +fn Main() -> i32 { + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/assert/fail_intrinsic_str_type.carbon:[[@LINE+3]]: type error in __intrinsic_assert argument 1 + // CHECK:STDERR: expected: String + // CHECK:STDERR: actual: i32 + __intrinsic_assert(true, 1); + return 0; +} diff --git a/explorer/testdata/pointer/fail_delete_uninit.carbon b/explorer/testdata/pointer/fail_delete_uninit.carbon new file mode 100644 index 000000000000..aff473cfc3a2 --- /dev/null +++ b/explorer/testdata/pointer/fail_delete_uninit.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 api; + +fn Main() -> i32 { + var p: i32*; + // CHECK:STDERR: RUNTIME ERROR: {{.*}}/explorer/testdata/pointer/fail_delete_uninit.carbon:[[@LINE+1]]: undefined behavior: access to uninitialized value Uninit> + heap.Delete(p); + return 0; +} diff --git a/explorer/testdata/pointer/fail_intrinsic_delete_no_args.carbon b/explorer/testdata/pointer/fail_intrinsic_delete_no_args.carbon new file mode 100644 index 000000000000..3e232c8ee092 --- /dev/null +++ b/explorer/testdata/pointer/fail_intrinsic_delete_no_args.carbon @@ -0,0 +1,15 @@ +// 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 api; + +fn Main() -> i32 { + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/pointer/fail_intrinsic_delete_no_args.carbon:[[@LINE+1]]: __intrinsic_delete takes 1 argument + __intrinsic_delete(); + return 0; +} diff --git a/explorer/testdata/pointer/fail_intrinsic_delete_type.carbon b/explorer/testdata/pointer/fail_intrinsic_delete_type.carbon new file mode 100644 index 000000000000..cd98752808be --- /dev/null +++ b/explorer/testdata/pointer/fail_intrinsic_delete_type.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: %{not} %{explorer-run} +// RUN: %{not} %{explorer-run-trace} + +package ExplorerTest api; + +fn Main() -> i32 { + var x: i32; + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/pointer/fail_intrinsic_delete_type.carbon:[[@LINE+3]]: type error in * + // CHECK:STDERR: expected a pointer type + // CHECK:STDERR: actual: i32 + __intrinsic_delete(x); + return 0; +} diff --git a/explorer/testdata/pointer/fail_intrinsic_new_no_args.carbon b/explorer/testdata/pointer/fail_intrinsic_new_no_args.carbon new file mode 100644 index 000000000000..282ee60db46a --- /dev/null +++ b/explorer/testdata/pointer/fail_intrinsic_new_no_args.carbon @@ -0,0 +1,15 @@ +// 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 api; + +fn Main() -> i32 { + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/pointer/fail_intrinsic_new_no_args.carbon:[[@LINE+1]]: __intrinsic_new takes 1 argument + __intrinsic_new(); + return 0; +} diff --git a/explorer/testdata/pointer/new_and_delete_class.carbon b/explorer/testdata/pointer/new_and_delete_class.carbon new file mode 100644 index 000000000000..8f6e3da91d3b --- /dev/null +++ b/explorer/testdata/pointer/new_and_delete_class.carbon @@ -0,0 +1,23 @@ +// 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: result: 0 + +package ExplorerTest api; + +class C { + fn DoPrint() { Print("test"); } +} + +fn Main() -> i32 { + var p: auto = heap.New(C); + var y: auto = *p; + // The following line would fail with: "could not find `y: auto`" + // y.DoPrint(); + heap.Delete(p); + return 0; +} diff --git a/explorer/testdata/pointer/new_and_delete_fn.carbon b/explorer/testdata/pointer/new_and_delete_fn.carbon new file mode 100644 index 000000000000..b20041b6540a --- /dev/null +++ b/explorer/testdata/pointer/new_and_delete_fn.carbon @@ -0,0 +1,21 @@ +// 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: test +// CHECK:STDOUT: result: 0 + +package ExplorerTest api; + +fn F() { Print("test"); } + +fn Main() -> i32 { + var p: auto = heap.New(F); + var y: auto = *p; + y(); + heap.Delete(p); + return 0; +} diff --git a/explorer/testdata/random/fail_empty_range.carbon b/explorer/testdata/random/fail_empty_range.carbon new file mode 100644 index 000000000000..cf5aabbaec00 --- /dev/null +++ b/explorer/testdata/random/fail_empty_range.carbon @@ -0,0 +1,15 @@ +// 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} +// CHECK:STDERR: RUNTIME ERROR: {{.*}}/explorer/data/prelude.carbon:{{.*}}: Rand inputs must be ordered for a non-empty range: 0 must be less than 0 + +package ExplorerTest api; + +fn Main() -> i32 { + Rand(0, 0); + return 0; +} diff --git a/explorer/testdata/random/fail_intrinsic_no_args.carbon b/explorer/testdata/random/fail_intrinsic_no_args.carbon new file mode 100644 index 000000000000..f44bf5ab68cf --- /dev/null +++ b/explorer/testdata/random/fail_intrinsic_no_args.carbon @@ -0,0 +1,15 @@ +// 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 api; + +fn Main() -> i32 { + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/random/fail_intrinsic_no_args.carbon:[[@LINE+1]]: Rand takes 2 arguments, received 0 + __intrinsic_rand(); + return 0; +} diff --git a/explorer/testdata/random/fail_intrinsic_type0.carbon b/explorer/testdata/random/fail_intrinsic_type0.carbon new file mode 100644 index 000000000000..3d6bd5adc782 --- /dev/null +++ b/explorer/testdata/random/fail_intrinsic_type0.carbon @@ -0,0 +1,17 @@ +// 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 api; + +fn Main() -> i32 { + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/random/fail_intrinsic_type0.carbon:[[@LINE+3]]: type error in Rand argument 0 + // CHECK:STDERR: expected: i32 + // CHECK:STDERR: actual: String + __intrinsic_rand("a", 1); + return 0; +} diff --git a/explorer/testdata/random/fail_intrinsic_type1.carbon b/explorer/testdata/random/fail_intrinsic_type1.carbon new file mode 100644 index 000000000000..1c7c36750195 --- /dev/null +++ b/explorer/testdata/random/fail_intrinsic_type1.carbon @@ -0,0 +1,17 @@ +// 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 api; + +fn Main() -> i32 { + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/random/fail_intrinsic_type1.carbon:[[@LINE+3]]: type error in Rand argument 1 + // CHECK:STDERR: expected: i32 + // CHECK:STDERR: actual: String + __intrinsic_rand(1, "a"); + return 0; +} diff --git a/explorer/testdata/random/fail_reverse_range.carbon b/explorer/testdata/random/fail_reverse_range.carbon new file mode 100644 index 000000000000..fa81b37d2e8b --- /dev/null +++ b/explorer/testdata/random/fail_reverse_range.carbon @@ -0,0 +1,15 @@ +// 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} +// CHECK:STDERR: RUNTIME ERROR: {{.*}}/explorer/data/prelude.carbon:{{.*}}: Rand inputs must be ordered for a non-empty range: 1 must be less than -1 + +package ExplorerTest api; + +fn Main() -> i32 { + Rand(1, -1); + return 0; +} diff --git a/explorer/testdata/random/max_range.carbon b/explorer/testdata/random/max_range.carbon new file mode 100644 index 000000000000..ca1df3749f93 --- /dev/null +++ b/explorer/testdata/random/max_range.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: result: 0 + +package ExplorerTest api; + +fn Main() -> i32 { + // -2147483648 is unsupported as a literal, but we can do it with a decrement. + var low: i32 = -2147483647; + low -= 1; + var high: i32 = 2147483647; + Rand(low, high); + return 0; +} diff --git a/explorer/testdata/random/random.carbon b/explorer/testdata/random/random.carbon index 8ce1493e6e9f..2c01b3772bba 100644 --- a/explorer/testdata/random/random.carbon +++ b/explorer/testdata/random/random.carbon @@ -9,15 +9,13 @@ // CHECK:STDOUT: result: 0 package ExplorerTest api; -fn test(para: i32)->bool{ - return true; -} + fn Main() -> i32 { - var i : i32 = Rand(0,100); - var j : i32 = Rand(0,100); - if(i == j){ + var i: i32 = Rand(0, 100); + var j: i32 = Rand(0, 100); + if (i == j) { Print("HALLO WELT"); - }else{ + } else { Print("Nice!"); } return 0;