diff --git a/src/hotspot/share/utilities/align.hpp b/src/hotspot/share/utilities/align.hpp index 4640f05e4d0..935781a5561 100644 --- a/src/hotspot/share/utilities/align.hpp +++ b/src/hotspot/share/utilities/align.hpp @@ -72,7 +72,9 @@ constexpr T align_down(T size, A alignment) { template::value)> constexpr T align_up(T size, A alignment) { - T adjusted = checked_cast(size + alignment_mask(alignment)); + T mask = checked_cast(alignment_mask(alignment)); + assert(size <= std::numeric_limits::max() - mask, "overflow"); + T adjusted = size + mask; return align_down(adjusted, alignment); } diff --git a/test/hotspot/gtest/runtime/test_os_reserve_between.cpp b/test/hotspot/gtest/runtime/test_os_reserve_between.cpp index aad6acc095a..16e1bdd1b21 100644 --- a/test/hotspot/gtest/runtime/test_os_reserve_between.cpp +++ b/test/hotspot/gtest/runtime/test_os_reserve_between.cpp @@ -304,12 +304,12 @@ TEST_VM(os, attempt_reserve_memory_randomization_cornercases) { // Zero-sized range test_attempt_reserve_memory_between(nullptr, nullptr, ps, ag, false, Expect::failure()); test_attempt_reserve_memory_between((char*)(3 * G), (char*)(3 * G), ps, ag, false, Expect::dontcare(), __LINE__); - test_attempt_reserve_memory_between((char*)SIZE_MAX, (char*)SIZE_MAX, ps, ag, false, Expect::failure(), __LINE__); + test_attempt_reserve_memory_between((char*)SIZE_MAX-ag, (char*)SIZE_MAX-ag, ps, ag, false, Expect::failure(), __LINE__); test_attempt_reserve_memory_between(nullptr, nullptr, ps, ag, true, Expect::failure()); test_attempt_reserve_memory_between((char*)(3 * G), (char*)(3 * G), ps, ag, true, Expect::dontcare(), __LINE__); test_attempt_reserve_memory_between((char*)(3 * G), (char*)(3 * G), ps, ag, true, Expect::dontcare(), __LINE__); - test_attempt_reserve_memory_between((char*)SIZE_MAX, (char*)SIZE_MAX, ps, ag, true, Expect::failure(), __LINE__); + test_attempt_reserve_memory_between((char*)SIZE_MAX-ag, (char*)SIZE_MAX-ag, ps, ag, true, Expect::failure(), __LINE__); // Full size // Note: paradoxically, success is not guaranteed here, since a significant portion of the attach points diff --git a/test/hotspot/gtest/utilities/test_align.cpp b/test/hotspot/gtest/utilities/test_align.cpp index f5e6b9d9646..4efcf14a7f0 100644 --- a/test/hotspot/gtest/utilities/test_align.cpp +++ b/test/hotspot/gtest/utilities/test_align.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ #include "precompiled.hpp" #include "utilities/align.hpp" +#include "utilities/checkedCast.hpp" #include "utilities/formatBuffer.hpp" #include "utilities/globalDefinitions.hpp" #include "unittest.hpp" @@ -30,7 +31,7 @@ #include // A few arbitrarily chosen values to test the align functions on. -static constexpr uint64_t values[] = {1, 3, 10, 345, 1023, 1024, 1025, 23909034, INT_MAX, uint64_t(-1) / 2, uint64_t(-1) / 2 + 100, uint64_t(-1)}; +static constexpr uint64_t values[] = {1, 3, 10, 345, 1023, 1024, 1025, 23909034, INT_MAX, uint64_t(-1) / 2, uint64_t(-1) / 2 + 100, ~(uint64_t(1) << 62)}; template static constexpr T max_alignment() { @@ -195,3 +196,33 @@ TEST(Align, alignments) { test_alignments(); } + +#ifdef ASSERT +template +static void test_fail_alignment() { + A alignment = max_alignment(); + T value = align_down(std::numeric_limits::max(), alignment) + 1; + // Aligning up would overflow, as there is not enough room for alignment + T aligned = align_up(value, alignment); +} + +TEST_VM_ASSERT(Align, fail_alignments_same_size) { + test_fail_alignment(); +} + +TEST_VM_ASSERT(Align, fail_alignments_unsigned_signed) { + test_fail_alignment(); +} + +TEST_VM_ASSERT(Align, fail_alignments_signed_unsigned) { + test_fail_alignment(); +} + +TEST_VM_ASSERT(Align, fail_alignments_small_large) { + test_fail_alignment(); +} + +TEST_VM_ASSERT(Align, fail_alignments_large_small) { + test_fail_alignment(); +} +#endif // ASSERT