From 12a880921dcf39a72ae43645f0188f8bec6c3fb4 Mon Sep 17 00:00:00 2001 From: "Wu, Xin-Chuan" Date: Wed, 5 Aug 2026 10:49:02 -0700 Subject: [PATCH 1/6] Fix matrix index bounds validation --- include/tinymatrix.hpp | 13 +++++++++---- pybind11/intelqs_py.cpp | 21 ++++++++++----------- unit_test/import_iqs.py | 19 +++++++++++++++++++ unit_test/include/tinymatrix_test.hpp | 13 +++++++++++++ 4 files changed, 51 insertions(+), 15 deletions(-) diff --git a/include/tinymatrix.hpp b/include/tinymatrix.hpp index b49e5c4d..e5d068fa 100644 --- a/include/tinymatrix.hpp +++ b/include/tinymatrix.hpp @@ -18,6 +18,7 @@ #include #include #include +#include /// \addtogroup util /// @{ @@ -141,8 +142,10 @@ class TinyMatrix /// \pre inumRows() && "Row index out of range"); - assert(j < this->numCols() && "Column index out of range"); + if (i >= this->numRows()) + throw std::out_of_range("TinyMatrix row index out of range"); + if (j >= this->numCols()) + throw std::out_of_range("TinyMatrix column index out of range"); return data_[i][j]; } @@ -154,8 +157,10 @@ class TinyMatrix /// \pre inumRows() && "Row index out of range"); - assert(j < this->numCols() && "Column index out of range"); + if (i >= this->numRows()) + throw std::out_of_range("TinyMatrix row index out of range"); + if (j >= this->numCols()) + throw std::out_of_range("TinyMatrix column index out of range"); return data_[i][j]; } diff --git a/pybind11/intelqs_py.cpp b/pybind11/intelqs_py.cpp index aa025a18..6889bc6d 100644 --- a/pybind11/intelqs_py.cpp +++ b/pybind11/intelqs_py.cpp @@ -96,16 +96,15 @@ PYBIND11_MODULE(intelqs_py, m) .def(py::init<>()) .def(py::init<>()) // Access element: - .def("__getitem__", [](const iqs::ChiMatrix &a, std::pair i, int column) { - if (i.first > 4) throw py::index_error(); - if (i.second > 4) throw py::index_error(); -std::cout << "ciao\n"; + .def("__getitem__", [](const iqs::ChiMatrix &a, std::pair i) { + if (i.first < 0 || i.first >= 4) throw py::index_error(); + if (i.second < 0 || i.second >= 4) throw py::index_error(); return a(i.first, i.second); }, py::is_operator()) // Set element: .def("__setitem__", [](iqs::ChiMatrix &a, std::pair i, ComplexDP value) { - if (i.first > 4) throw py::index_error(); - if (i.second > 4) throw py::index_error(); + if (i.first < 0 || i.first >= 4) throw py::index_error(); + if (i.second < 0 || i.second >= 4) throw py::index_error(); a(i.first, i.second) = value; }, py::is_operator()) #if 0 @@ -147,15 +146,15 @@ std::cout << "ciao\n"; .def(py::init<>()) .def(py::init<>()) // Access element: - .def("__getitem__", [](const iqs::ChiMatrix &a, std::pair i, int column) { - if (i.first > 16) throw py::index_error(); - if (i.second > 16) throw py::index_error(); + .def("__getitem__", [](const iqs::ChiMatrix &a, std::pair i) { + if (i.first < 0 || i.first >= 16) throw py::index_error(); + if (i.second < 0 || i.second >= 16) throw py::index_error(); return a(i.first, i.second); }, py::is_operator()) // Set element: .def("__setitem__", [](iqs::ChiMatrix &a, std::pair i, ComplexDP value) { - if (i.first > 16) throw py::index_error(); - if (i.second > 16) throw py::index_error(); + if (i.first < 0 || i.first >= 16) throw py::index_error(); + if (i.second < 0 || i.second >= 16) throw py::index_error(); a(i.first, i.second) = value; }, py::is_operator()) .def("SolveEigenSystem", &iqs::ChiMatrix::SolveEigenSystem) diff --git a/unit_test/import_iqs.py b/unit_test/import_iqs.py index c8c43069..4fb4f3a2 100644 --- a/unit_test/import_iqs.py +++ b/unit_test/import_iqs.py @@ -4,6 +4,25 @@ sys.path.insert(0, "../build/lib/") import intelqs_py as iqs + +def assert_index_error(operation): + try: + operation() + except IndexError: + return + raise AssertionError("Invalid matrix index did not raise IndexError") + + +for matrix_type, dimension in ((iqs.CM4x4, 4), (iqs.CM16x16, 16)): + matrix = matrix_type() + matrix[dimension - 1, dimension - 1] = 1 + 2j + assert matrix[dimension - 1, dimension - 1] == 1 + 2j + + for invalid_index in ((-1, 0), (0, -1), (dimension, 0), (0, dimension)): + assert_index_error(lambda index=invalid_index: matrix[index]) + assert_index_error(lambda index=invalid_index: matrix.__setitem__(index, 0j)) + + iqs.EnvInit() rank = iqs.MPIEnvironment.GetRank() diff --git a/unit_test/include/tinymatrix_test.hpp b/unit_test/include/tinymatrix_test.hpp index a47ef2c4..95379df2 100644 --- a/unit_test/include/tinymatrix_test.hpp +++ b/unit_test/include/tinymatrix_test.hpp @@ -162,4 +162,17 @@ TEST_F(TinyMatrixTest, ComplexDP) ////////////////////////////////////////////////////////////////////////////// +TEST_F(TinyMatrixTest, OutOfRangeAccess) +{ + iqs::TinyMatrix mat; + const iqs::TinyMatrix& const_mat = mat; + + ASSERT_THROW(mat(2, 0), std::out_of_range); + ASSERT_THROW(mat(0, 3), std::out_of_range); + ASSERT_THROW(const_mat(2, 0), std::out_of_range); + ASSERT_THROW(const_mat(0, 3), std::out_of_range); +} + +////////////////////////////////////////////////////////////////////////////// + #endif // header guard TINYMATRIX_TEST_HPP From 1eab81fc2be2f9e50a71f89d1c90d5f4b562b554 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Aug 2026 18:09:20 +0000 Subject: [PATCH 2/6] Fix Dockerfile: replace deprecated apt-key with gpg for Intel MKL key Co-authored-by: ryanxw <16125496+ryanxw@users.noreply.github.com> --- Dockerfile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8482fef6..f1269d99 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,10 +41,9 @@ RUN tar -xzf cmake-3.15.2-Linux-x86_64.tar.gz -C /usr/local/ --strip-components= # Fetch and install the Intel MKL libraries required for building the Intel-QS simulator. WORKDIR swpkgs/mkl -RUN wget "https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB" -RUN apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB -RUN rm GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB -RUN sh -c 'echo deb https://apt.repos.intel.com/mkl all main > /etc/apt/sources.list.d/intel-mkl.list' +RUN apt-get install -y gpg +RUN wget -qO - "https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB" | gpg --dearmor -o /usr/share/keyrings/intel-sw-products.gpg +RUN sh -c 'echo "deb [signed-by=/usr/share/keyrings/intel-sw-products.gpg] https://apt.repos.intel.com/mkl all main" > /etc/apt/sources.list.d/intel-mkl.list' RUN apt-get update RUN apt-get install -y intel-mkl-64bit-2019.2-057 # Set the (global) environment variable MKLROOT to facilitate the build process. From dc1b12815f07fe5ae8831a65c7d16aae92f267a1 Mon Sep 17 00:00:00 2001 From: "X. Ryan Wu" Date: Tue, 11 Aug 2026 11:37:32 -0700 Subject: [PATCH 3/6] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- unit_test/import_iqs.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unit_test/import_iqs.py b/unit_test/import_iqs.py index 4fb4f3a2..0b17ae23 100644 --- a/unit_test/import_iqs.py +++ b/unit_test/import_iqs.py @@ -16,7 +16,8 @@ def assert_index_error(operation): for matrix_type, dimension in ((iqs.CM4x4, 4), (iqs.CM16x16, 16)): matrix = matrix_type() matrix[dimension - 1, dimension - 1] = 1 + 2j - assert matrix[dimension - 1, dimension - 1] == 1 + 2j + if matrix[dimension - 1, dimension - 1] != 1 + 2j: + raise AssertionError("Matrix element assignment/getitem failed") for invalid_index in ((-1, 0), (0, -1), (dimension, 0), (0, dimension)): assert_index_error(lambda index=invalid_index: matrix[index]) From aed9dc126751cfdd19128300b79e42669f536001 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 11 Aug 2026 18:38:01 +0000 Subject: [PATCH 4/6] Document matrix bounds exceptions Co-authored-by: ryanxw <16125496+ryanxw@users.noreply.github.com> --- include/tinymatrix.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/tinymatrix.hpp b/include/tinymatrix.hpp index e5d068fa..add4cab2 100644 --- a/include/tinymatrix.hpp +++ b/include/tinymatrix.hpp @@ -139,7 +139,7 @@ class TinyMatrix /// Access a matrix element of a const matrix /// \param i the row index /// \param j the column index - /// \pre i=numRows() or j>=numCols() value_type operator()(size_type i, size_type j) const { if (i >= this->numRows()) @@ -154,7 +154,7 @@ class TinyMatrix /// Access a matrix element. /// \param i the row index /// \param j the column index - /// \pre i=numRows() or j>=numCols() reference operator()(size_type i, size_type j) { if (i >= this->numRows()) From 94eb0dbb90cca42c7a470a464d4769f4a294cdc9 Mon Sep 17 00:00:00 2001 From: "Wu, Xin-Chuan" Date: Thu, 13 Aug 2026 09:25:50 -0700 Subject: [PATCH 5/6] Validate Python qubit indices --- include/permutation.hpp | 9 ++-- pybind11/intelqs_py.cpp | 107 ++++++++++++++++++++++++++++++---------- unit_test/import_iqs.py | 12 ++++- 3 files changed, 95 insertions(+), 33 deletions(-) diff --git a/include/permutation.hpp b/include/permutation.hpp index bab1d75e..29d53d94 100644 --- a/include/permutation.hpp +++ b/include/permutation.hpp @@ -68,20 +68,17 @@ class Permutation unsigned operator[](std::size_t i) const { - assert(i < num_elements); - return (unsigned) map[i]; + return (unsigned) map.at(i); } unsigned operator[](unsigned i) const { - assert(i < num_elements); - return map[i]; + return map.at(i); } int operator[](int i) const { - assert(i < num_elements); - return (int)map[i]; + return (int)map.at(i); } ///////////////////////////////////////////////////////////////////////////////////////// diff --git a/pybind11/intelqs_py.cpp b/pybind11/intelqs_py.cpp index 6889bc6d..e3417f2c 100644 --- a/pybind11/intelqs_py.cpp +++ b/pybind11/intelqs_py.cpp @@ -49,6 +49,46 @@ void EnvFinalizeDummyRanks() } } +using QubitRegisterDP = QubitRegister; + +void ValidateQubitIndex(const QubitRegisterDP ®ister_, unsigned qubit) +{ + if (qubit >= register_.NumQubits()) + throw py::index_error("Qubit index out of range"); +} + +template +auto WithValidQubit(Return (QubitRegisterDP::*method)(unsigned, Args...)) +{ + return [method](QubitRegisterDP ®ister_, unsigned qubit, Args... args) -> Return { + ValidateQubitIndex(register_, qubit); + return (register_.*method)(qubit, args...); + }; +} + +template +auto WithValidQubits(Return (QubitRegisterDP::*method)(unsigned, unsigned, Args...)) +{ + return [method](QubitRegisterDP ®ister_, unsigned qubit1, unsigned qubit2, + Args... args) -> Return { + ValidateQubitIndex(register_, qubit1); + ValidateQubitIndex(register_, qubit2); + return (register_.*method)(qubit1, qubit2, args...); + }; +} + +template +auto WithValidQubits(Return (QubitRegisterDP::*method)(unsigned, unsigned, unsigned)) +{ + return [method](QubitRegisterDP ®ister_, unsigned qubit1, unsigned qubit2, + unsigned qubit3) -> Return { + ValidateQubitIndex(register_, qubit1); + ValidateQubitIndex(register_, qubit2); + ValidateQubitIndex(register_, qubit3); + return (register_.*method)(qubit1, qubit2, qubit3); + }; +} + ////////////////////////////////////////////////////////////////////////////// // PYBIND CODE for the Intel Quantum Simulator library ////////////////////////////////////////////////////////////////////////////// @@ -199,32 +239,33 @@ PYBIND11_MODULE(intelqs_py, m) { sizeof(ComplexDP) }); /* Strides (in bytes) for each index */ }) // One-qubit gates: - .def("ApplyRotationX", &QubitRegister::ApplyRotationX) - .def("ApplyRotationY", &QubitRegister::ApplyRotationY) - .def("ApplyRotationZ", &QubitRegister::ApplyRotationZ) - .def("ApplyPauliX", &QubitRegister::ApplyPauliX) - .def("ApplyPauliY", &QubitRegister::ApplyPauliY) - .def("ApplyPauliZ", &QubitRegister::ApplyPauliZ) - .def("ApplyPauliSqrtX", &QubitRegister::ApplyPauliSqrtX) - .def("ApplyPauliSqrtY", &QubitRegister::ApplyPauliSqrtY) - .def("ApplyPauliSqrtZ", &QubitRegister::ApplyPauliSqrtZ) - .def("ApplyT", &QubitRegister::ApplyT) - .def("ApplyRotationXY", &QubitRegister::ApplyRotationXY) - .def("ApplyHadamard", &QubitRegister::ApplyHadamard) + .def("ApplyRotationX", WithValidQubit(&QubitRegisterDP::ApplyRotationX)) + .def("ApplyRotationY", WithValidQubit(&QubitRegisterDP::ApplyRotationY)) + .def("ApplyRotationZ", WithValidQubit(&QubitRegisterDP::ApplyRotationZ)) + .def("ApplyPauliX", WithValidQubit(&QubitRegisterDP::ApplyPauliX)) + .def("ApplyPauliY", WithValidQubit(&QubitRegisterDP::ApplyPauliY)) + .def("ApplyPauliZ", WithValidQubit(&QubitRegisterDP::ApplyPauliZ)) + .def("ApplyPauliSqrtX", WithValidQubit(&QubitRegisterDP::ApplyPauliSqrtX)) + .def("ApplyPauliSqrtY", WithValidQubit(&QubitRegisterDP::ApplyPauliSqrtY)) + .def("ApplyPauliSqrtZ", WithValidQubit(&QubitRegisterDP::ApplyPauliSqrtZ)) + .def("ApplyT", WithValidQubit(&QubitRegisterDP::ApplyT)) + .def("ApplyRotationXY", WithValidQubit(&QubitRegisterDP::ApplyRotationXY)) + .def("ApplyHadamard", WithValidQubit(&QubitRegisterDP::ApplyHadamard)) // Two-qubit gates: - .def("ApplySwap", &QubitRegister::ApplySwap) - .def("ApplyCRotationX", &QubitRegister::ApplyCRotationX) - .def("ApplyCRotationY", &QubitRegister::ApplyCRotationY) - .def("ApplyCRotationZ", &QubitRegister::ApplyCRotationZ) - .def("ApplyCPauliX", &QubitRegister::ApplyCPauliX) - .def("ApplyCPauliY", &QubitRegister::ApplyCPauliY) - .def("ApplyCPauliZ", &QubitRegister::ApplyCPauliZ) - .def("ApplyCPauliSqrtZ", &QubitRegister::ApplyCPauliSqrtZ) - .def("ApplyCHadamard", &QubitRegister::ApplyCHadamard) + .def("ApplySwap", WithValidQubits(&QubitRegisterDP::ApplySwap)) + .def("ApplyCRotationX", WithValidQubits(&QubitRegisterDP::ApplyCRotationX)) + .def("ApplyCRotationY", WithValidQubits(&QubitRegisterDP::ApplyCRotationY)) + .def("ApplyCRotationZ", WithValidQubits(&QubitRegisterDP::ApplyCRotationZ)) + .def("ApplyCPauliX", WithValidQubits(&QubitRegisterDP::ApplyCPauliX)) + .def("ApplyCPauliY", WithValidQubits(&QubitRegisterDP::ApplyCPauliY)) + .def("ApplyCPauliZ", WithValidQubits(&QubitRegisterDP::ApplyCPauliZ)) + .def("ApplyCPauliSqrtZ", WithValidQubits(&QubitRegisterDP::ApplyCPauliSqrtZ)) + .def("ApplyCHadamard", WithValidQubits(&QubitRegisterDP::ApplyCHadamard)) // Custom 1-qubit gate and controlled 2-qubit gates: .def("Apply1QubitGate", [](QubitRegister &a, unsigned qubit, py::array_t matrix ) { + ValidateQubitIndex(a, qubit); py::buffer_info buf = matrix.request(); if (buf.ndim != 2) throw std::runtime_error("Number of dimensions must be two."); @@ -242,6 +283,8 @@ PYBIND11_MODULE(intelqs_py, m) .def("ApplyControlled1QubitGate", [](QubitRegister &a, unsigned control, unsigned qubit, py::array_t matrix ) { + ValidateQubitIndex(a, control); + ValidateQubitIndex(a, qubit); py::buffer_info buf = matrix.request(); if (buf.ndim != 2) throw std::runtime_error("Number of dimensions must be two."); @@ -261,17 +304,21 @@ PYBIND11_MODULE(intelqs_py, m) #if 1 .def("ApplyChannel", [](QubitRegister &a, unsigned qubit, iqs::ChiMatrix chi) { + ValidateQubitIndex(a, qubit); a.ApplyChannel(qubit, chi); }, "Apply 1-qubit channel provided via its chi-matrix.") .def("ApplyChannel", [](QubitRegister &a, unsigned qubit1, unsigned qubit2, iqs::ChiMatrix chi) { + ValidateQubitIndex(a, qubit1); + ValidateQubitIndex(a, qubit2); a.ApplyChannel(qubit1, qubit2, chi); }, "Apply 2-qubit channel provided via its chi-matrix.") #else .def("ApplyChannel", [](QubitRegister &a, unsigned qubit, py::array_t matrix ) { + ValidateQubitIndex(a, qubit); py::buffer_info buf = matrix.request(); if (buf.ndim != 2) throw std::runtime_error("Number of dimensions must be two."); @@ -289,6 +336,8 @@ PYBIND11_MODULE(intelqs_py, m) .def("ApplyChannel", [](QubitRegister &a, unsigned qubit1, unsigned qubit2, py::array_t matrix ) { + ValidateQubitIndex(a, qubit1); + ValidateQubitIndex(a, qubit2); py::buffer_info buf = matrix.request(); if (buf.ndim != 2) throw std::runtime_error("Number of dimensions must be two."); @@ -308,7 +357,7 @@ PYBIND11_MODULE(intelqs_py, m) }, "Apply 1-qubit channel provided via its chi-matrix.") #endif // Three-qubit gates: - .def("ApplyToffoli", &QubitRegister::ApplyToffoli) + .def("ApplyToffoli", WithValidQubits(&QubitRegisterDP::ApplyToffoli)) // State initialization: .def("Initialize", (void (QubitRegister::*)(std::string, std::size_t )) @@ -323,12 +372,18 @@ PYBIND11_MODULE(intelqs_py, m) .def("SetRngPtr", &QubitRegister::SetRngPtr) .def("SetSeedRngPtr", &QubitRegister::SetSeedRngPtr) // State measurement and collapse: - .def("GetProbability", &QubitRegister::GetProbability) - .def("CollapseQubit", &QubitRegister::CollapseQubit) + .def("GetProbability", WithValidQubit(&QubitRegisterDP::GetProbability)) + .def("CollapseQubit", WithValidQubit(&QubitRegisterDP::CollapseQubit)) // Recall that the collapse selects: 'false'=|0> , 'true'=|1> .def("Normalize", &QubitRegister::Normalize) .def("AmplitudeWiseScalarMultiplication", &QubitRegister::AmplitudeWiseScalarMultiplication) - .def("ExpectationValue", &QubitRegister::ExpectationValue) + .def("ExpectationValue", + [](QubitRegisterDP &a, std::vector qubits, + std::vector observables, QubitRegisterDP::BaseType coeff) { + for (unsigned qubit : qubits) + ValidateQubitIndex(a, qubit); + return a.ExpectationValue(qubits, observables, coeff); + }) // Other quantum operations: .def("ComputeNorm", &QubitRegister::ComputeNorm) .def("ComputeOverlap", &QubitRegister::ComputeOverlap) @@ -337,7 +392,7 @@ PYBIND11_MODULE(intelqs_py, m) .def("GetT2", &QubitRegister::GetT2) .def("GetTphi", &QubitRegister::GetTphi) .def("SetNoiseTimescales", &QubitRegister::SetNoiseTimescales) - .def("ApplyNoiseGate", &QubitRegister::ApplyNoiseGate) + .def("ApplyNoiseGate", WithValidQubit(&QubitRegisterDP::ApplyNoiseGate)) // Utility functions: .def("Print", [](QubitRegister &a, std::string description) { diff --git a/unit_test/import_iqs.py b/unit_test/import_iqs.py index 0b17ae23..e057da8e 100644 --- a/unit_test/import_iqs.py +++ b/unit_test/import_iqs.py @@ -10,7 +10,7 @@ def assert_index_error(operation): operation() except IndexError: return - raise AssertionError("Invalid matrix index did not raise IndexError") + raise AssertionError("Invalid index did not raise IndexError") for matrix_type, dimension in ((iqs.CM4x4, 4), (iqs.CM16x16, 16)): @@ -31,6 +31,16 @@ def assert_index_error(operation): psi = iqs.QubitRegister(2, "base", 0, 0); +one_qubit_psi = iqs.QubitRegister(1, "base", 0, 0) +for invalid_operation in ( + lambda: one_qubit_psi.ApplyHadamard(1), + lambda: one_qubit_psi.GetProbability(1), + lambda: one_qubit_psi.CollapseQubit(1, False), + lambda: one_qubit_psi.ApplyCPauliX(0, 1), + lambda: one_qubit_psi.ApplyCPauliX(1, 0), +): + assert_index_error(invalid_operation) + print("The IQS library was successfully imported and initialized.") iqs.EnvFinalize() From 2dc031aad7ce3def50c982f1e35bece1dd7327f7 Mon Sep 17 00:00:00 2001 From: "Wu, Xin-Chuan" Date: Thu, 13 Aug 2026 09:40:02 -0700 Subject: [PATCH 6/6] Fix unit tests. --- unit_test/include/single_qubit_gates_test.hpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/unit_test/include/single_qubit_gates_test.hpp b/unit_test/include/single_qubit_gates_test.hpp index 47f58433..83f02234 100644 --- a/unit_test/include/single_qubit_gates_test.hpp +++ b/unit_test/include/single_qubit_gates_test.hpp @@ -121,28 +121,17 @@ TEST_F(SingleQubitGatesTest, CustomGate) ////////////////////////////////////////////////////////////////////////////// -TEST_F(SingleQubitGatesTest, DeathTest) +TEST_F(SingleQubitGatesTest, OutOfRangeQubit) { - // Skip death-tests if compiler flag NDEBUG is defined. -#ifdef NDEBUG - GTEST_SKIP() << "INFO: test skipped when compiler flag NDEBUG is not defined."; -#endif - - // Skip death-tests if MPI size > 1. - if (iqs::mpi::Environment::GetStateSize() > 1) - GTEST_SKIP(); - // |psi> = |0000000000> = |"0"> iqs::QubitRegister psi (num_qubits_,"base",0); - // To switch off the warning message about DEATH test not being thread safe. - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; // Qubit index beyond the register size. int qubit = num_qubits_; - ASSERT_DEATH( psi.ApplyHadamard(qubit), ""); + ASSERT_THROW( psi.ApplyHadamard(qubit), std::out_of_range); // Negative qubit index. qubit = -1; - ASSERT_DEATH( psi.ApplyHadamard(qubit), ""); + ASSERT_THROW( psi.ApplyHadamard(qubit), std::out_of_range); } //////////////////////////////////////////////////////////////////////////////