changeset 33252:737ab816cb7b bytecode-interpreter

maint: merge default to bytecode-interpreter
author John W. Eaton <jwe@octave.org>
date Mon, 25 Mar 2024 14:00:49 -0400
parents 106a4a07742a (current diff) 93b856b2d87e (diff)
children 9f8fed12fa37
files libinterp/corefcn/variables.cc
diffstat 43 files changed, 133 insertions(+), 130 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/__isprimelarge__.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/__isprimelarge__.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -242,7 +242,7 @@
 
       if (g > 1)  // found GCD ==> exit loop properly
         {
-          error_unless (n % g == 0);  // theoretical possibility of GCD error
+          panic_unless (n % g == 0);  // theoretical possibility of GCD error
           return g;
         }
     }
--- a/libinterp/corefcn/cellfun.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/cellfun.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -1990,8 +1990,9 @@
 do_mat2cell_2d (const Array2D& a, const Array<octave_idx_type> *d, int nd)
 {
   Cell retval;
-  error_unless (nd == 1 || nd == 2);
-  error_unless (a.ndims () == 2);
+
+  panic_unless (nd == 1 || nd == 2);
+  panic_unless (a.ndims () == 2);
 
   if (mat2cell_mismatch (a.dims (), d, nd))
     return retval;
@@ -2047,7 +2048,8 @@
 do_mat2cell_nd (const ArrayND& a, const Array<octave_idx_type> *d, int nd)
 {
   Cell retval;
-  error_unless (nd >= 1);
+
+  panic_unless (nd >= 1);
 
   if (mat2cell_mismatch (a.dims (), d, nd))
     return retval;
@@ -2129,7 +2131,8 @@
 do_mat2cell (octave_value& a, const Array<octave_idx_type> *d, int nd)
 {
   Cell retval;
-  error_unless (nd >= 1);
+
+  panic_unless (nd >= 1);
 
   if (mat2cell_mismatch (a.dims (), d, nd))
     return retval;
--- a/libinterp/corefcn/daspk.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/daspk.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -68,7 +68,7 @@
 {
   ColumnVector retval;
 
-  error_unless (x.numel () == xdot.numel ());
+  panic_unless (x.numel () == xdot.numel ());
 
   octave_value_list args;
 
@@ -119,7 +119,7 @@
 {
   Matrix retval;
 
-  error_unless (x.numel () == xdot.numel ());
+  panic_unless (x.numel () == xdot.numel ());
 
   octave_value_list args;
 
--- a/libinterp/corefcn/dasrt.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/dasrt.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -69,7 +69,7 @@
 {
   ColumnVector retval;
 
-  error_unless (x.numel () == xdot.numel ());
+  panic_unless (x.numel () == xdot.numel ());
 
   octave_value_list args;
 
@@ -159,7 +159,7 @@
 {
   Matrix retval;
 
-  error_unless (x.numel () == xdot.numel ());
+  panic_unless (x.numel () == xdot.numel ());
 
   octave_value_list args;
 
--- a/libinterp/corefcn/dassl.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/dassl.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -67,7 +67,7 @@
 {
   ColumnVector retval;
 
-  error_unless (x.numel () == xdot.numel ());
+  panic_unless (x.numel () == xdot.numel ());
 
   octave_value_list args;
 
@@ -118,7 +118,7 @@
 {
   Matrix retval;
 
-  error_unless (x.numel () == xdot.numel ());
+  panic_unless (x.numel () == xdot.numel ());
 
   octave_value_list args;
 
--- a/libinterp/corefcn/data.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/data.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -8154,7 +8154,7 @@
           idx_vector col1 (':'), col2 (':'), sl1 (1, k), sl2 (0, k-1);
           retval = SparseT (retval.index (col1, sl1))
                    - SparseT (retval.index (col2, sl2));
-          error_unless (retval.columns () == k-1);
+          panic_unless (retval.columns () == k-1);
           order--;
           k--;
         }
@@ -8167,7 +8167,7 @@
           idx_vector col1 (':'), col2 (':'), sl1 (1, k), sl2 (0, k-1);
           retval = SparseT (retval.index (sl1, col1))
                    - SparseT (retval.index (sl2, col2));
-          error_unless (retval.rows () == k-1);
+          panic_unless (retval.rows () == k-1);
           order--;
           k--;
         }
--- a/libinterp/corefcn/error.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/error.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -633,12 +633,15 @@
 void
 error_system::vpanic (const char *fmt, va_list args)
 {
-  // Is there any point in trying to write the panic message to the
-  // diary?
+  // Earlier versions of Octave printed a message directly to std::cerr
+  // and called abort.  That might be acceptable behavior for some
+  // programs but for an interactive application like Octave, aborting
+  // the entire program when an internal programming error has been
+  // detected seems unnecessary and certainly provides a much worse user
+  // experience than simply generating an ordinary error message and
+  // attempting to return to the command prompt.
 
-  std::cerr << "panic: " << format_message (fmt, args) << std::endl;
-
-  abort ();
+  ::verror (fmt, args);
 }
 
 void
--- a/libinterp/corefcn/error.h	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/error.h	Mon Mar 25 14:00:49 2024 -0400
@@ -493,20 +493,23 @@
 extern OCTINTERP_API void
 parse_error_with_id (const char *id, const char *fmt, ...);
 
+// Use of the following macros (error_impossible, error_if, and
+// error_unless) is discouraged.  All of these will only display a
+// generic error of the form
+//
+//   impossible state reached in file 'FILE' at line 'N'
+//
+// If the state really is "impossible" to reach, then it is better to
+// use one of the corresponding panic* functions instead (see panic.h).
+//
+// See also the discussion here: https://octave.discourse.group/t/assert-panic-error-and-ndebug/5409
+
 #define error_impossible()                                              \
   ::error ("impossible state reached in file '%s' at line %d", __FILE__, __LINE__)
 
-#if defined (NDEBUG)
-#  define error_if(cond)
-#else
-#  define error_if(cond) do { if (cond) error_impossible (); } while (0)
-#endif
+#define error_if(cond) do { if (cond) error_impossible (); } while (0)
 
-#if defined (NDEBUG)
-#  define error_unless(cond)
-#else
-#  define error_unless(cond) error_if (! (cond))
-#endif
+#define error_unless(cond) error_if (! (cond))
 
 OCTAVE_BEGIN_NAMESPACE(octave)
 
--- a/libinterp/corefcn/graphics.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/graphics.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -5310,10 +5310,10 @@
   // Including ones we do don't implement?
 
   // FIXME: This function is probably never called without mode == "reset".
-  //        Verify this is the case with error_unless() (1/6/2017).
+  //        Verify this is the case with panic_unless() (1/6/2017).
   //        If there are reports of problems then figure out what code is
   //        calling it with the mode set to something else.
-  error_unless (mode == "reset");
+  panic_unless (mode == "reset");
 
   Matrix tlim (1, 2, 0.0);
   tlim(1) = 1;
--- a/libinterp/corefcn/input.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/input.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -32,7 +32,6 @@
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
-#include <cassert>
 
 #include <algorithm>
 #include <iostream>
--- a/libinterp/corefcn/kron.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/kron.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -55,8 +55,8 @@
 static MArray<T>
 kron (const MArray<R>& a, const MArray<T>& b)
 {
-  error_unless (a.ndims () == 2);
-  error_unless (b.ndims () == 2);
+  panic_unless (a.ndims () == 2);
+  panic_unless (b.ndims () == 2);
 
   octave_idx_type nra = a.rows ();
   octave_idx_type nrb = b.rows ();
@@ -86,7 +86,7 @@
 static MArray<T>
 kron (const MDiagArray2<R>& a, const MArray<T>& b)
 {
-  error_unless (b.ndims () == 2);
+  panic_unless (b.ndims () == 2);
 
   octave_idx_type nra = a.rows ();
   octave_idx_type nrb = b.rows ();
--- a/libinterp/corefcn/mex.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/mex.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -467,7 +467,8 @@
     mxArray *retval = m_val.as_mxArray (m_interleaved);
 
     // RETVAL is assumed to be an mxArray_matlab object.  Should we
-    // error_unless that condition here?
+    // panic_unless that condition here or just check and throw an
+    // error?
 
     if (retval)
       {
--- a/libinterp/corefcn/oct-map.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/oct-map.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -612,7 +612,7 @@
   for (octave_idx_type j = 0; j < nf; j++)
     {
       retval.m_vals.push_back (Cell (rd));
-      error_unless (retval.m_vals[j].numel () == n);
+      panic_unless (retval.m_vals[j].numel () == n);
       for (octave_idx_type i = 0; i < n; i++)
         retval.m_vals[j].xelem (i) = map_list[i].m_vals[j];
     }
@@ -1033,7 +1033,7 @@
           error (ee, "incompatible fields in struct assignment");
         }
 
-      error_unless (rhs1.m_keys.is_same (m_keys));
+      panic_unless (rhs1.m_keys.is_same (m_keys));
       assign (i, rhs1);
     }
 }
@@ -1081,7 +1081,7 @@
           error (ee, "incompatible fields in struct assignment");
         }
 
-      error_unless (rhs1.m_keys.is_same (m_keys));
+      panic_unless (rhs1.m_keys.is_same (m_keys));
       assign (i, j, rhs1);
     }
 }
@@ -1129,7 +1129,7 @@
           error (ee, "incompatible fields in struct assignment");
         }
 
-      error_unless (rhs1.m_keys.is_same (m_keys));
+      panic_unless (rhs1.m_keys.is_same (m_keys));
       assign (ia, rhs1);
     }
 }
--- a/libinterp/corefcn/oct-stream.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/oct-stream.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,7 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <cassert>
 #include <cctype>
 #include <cstring>
 
@@ -6679,7 +6678,7 @@
   std::ptrdiff_t input_buf_size
     = static_cast<std::ptrdiff_t> (input_buf_elts) * input_elt_size;
 
-  error_if (input_buf_size < 0);
+  panic_if (input_buf_size < 0);
 
   // Must also work and return correct type object for 0 elements to read.
   std::istream *isp = input_stream ();
--- a/libinterp/corefcn/panic.h	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/panic.h	Mon Mar 25 14:00:49 2024 -0400
@@ -38,8 +38,8 @@
 extern OCTINTERP_API void panic (const char *fmt, ...);
 
 // To allow the __FILE__ and __LINE__ macros to work as expected, the
-// panic_impossible, panic_if, panic_unless, error_impossible, error_if,
-// and error_unless symbols must be defined as macros.
+// panic_impossible, panic_if, and panic_unless symbols must be defined
+// as macros.
 
 #define panic_impossible()                                              \
   ::panic ("impossible state reached in file '%s' at line %d", __FILE__, __LINE__)
--- a/libinterp/corefcn/pr-output.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/pr-output.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -300,7 +300,7 @@
 pr_max_internal (const MArray<T>& m)
 {
   // We expect a 2-d array.
-  error_unless (m.ndims () == 2);
+  panic_unless (m.ndims () == 2);
 
   octave_idx_type nr = m.rows ();
   octave_idx_type nc = m.columns ();
@@ -680,7 +680,8 @@
 static inline float_display_format
 make_matrix_format (const MT& m)
 {
-  error_unless (m.ndims () == 2);
+  // We expect a 2-d array.
+  panic_unless (m.ndims () == 2);
 
   if (free_format)
     return float_display_format ();
@@ -1569,7 +1570,7 @@
 print_empty_matrix (std::ostream& os, octave_idx_type nr, octave_idx_type nc,
                     bool pr_as_read_syntax)
 {
-  error_unless (nr == 0 || nc == 0);
+  panic_unless (nr == 0 || nc == 0);
 
   if (pr_as_read_syntax)
     {
@@ -1591,7 +1592,7 @@
 print_empty_nd_array (std::ostream& os, const dim_vector& dims,
                       bool pr_as_read_syntax)
 {
-  error_unless (dims.any_zero ());
+  panic_unless (dims.any_zero ());
 
   if (pr_as_read_syntax)
     os << "zeros (" << dims.str (',') << ')';
--- a/libinterp/corefcn/schur.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/schur.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -46,7 +46,7 @@
   octave_value retval = a;
 
   octave_idx_type n = a.rows ();
-  error_unless (a.columns () == n);
+  panic_unless (a.columns () == n);
 
   const typename Matrix::element_type zero = typename Matrix::element_type ();
 
--- a/libinterp/corefcn/sparse-xdiv.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/sparse-xdiv.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,8 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <cassert>
-
 #include "Array-util.h"
 #include "lo-array-errwarn.h"
 #include "oct-cmplx.h"
--- a/libinterp/corefcn/sparse-xpow.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/sparse-xpow.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,8 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <cassert>
-
 #include <limits>
 
 #include "Array-util.h"
--- a/libinterp/corefcn/variables.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/variables.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -768,7 +768,7 @@
 
   int nargin = args.length ();
 
-  error_unless (var < nchoices);
+  panic_unless (var < nchoices);
 
   if (nargout > 0 || nargin == 0)
     retval = choices[var];
--- a/libinterp/corefcn/xdiv.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/xdiv.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,8 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <cassert>
-
 #include "Array-util.h"
 #include "CMatrix.h"
 #include "dMatrix.h"
--- a/libinterp/corefcn/xpow.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/corefcn/xpow.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,8 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <cassert>
-
 #include <limits>
 
 #include "Array-util.h"
--- a/libinterp/operators/ops.h	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/operators/ops.h	Mon Mar 25 14:00:49 2024 -0400
@@ -147,7 +147,7 @@
     OCTAVE_CAST_BASE_VALUE (CONCAT2 (octave_, t1)&, v1, a1);            \
     OCTAVE_CAST_BASE_VALUE (const CONCAT2 (octave_, t2)&, v2, a2);      \
                                                                         \
-    error_unless (idx.empty ());                                        \
+    panic_unless (idx.empty ());                                        \
     v1.matrix_ref () op v2.CONCAT2 (f, _value) ();                      \
                                                                         \
     return octave_value ();                                             \
@@ -162,7 +162,7 @@
     OCTAVE_CAST_BASE_VALUE (CONCAT2 (octave_, t1)&, v1, a1);            \
     OCTAVE_CAST_BASE_VALUE (const CONCAT2 (octave_, t2)&, v2, a2);      \
                                                                         \
-    error_unless (idx.empty ());                                        \
+    panic_unless (idx.empty ());                                        \
     fnop (v1.matrix_ref (), v2.CONCAT2 (f, _value) ());                 \
                                                                         \
     return octave_value ();                                             \
--- a/libinterp/parse-tree/oct-parse.yy	Sun Mar 24 16:53:18 2024 -0400
+++ b/libinterp/parse-tree/oct-parse.yy	Mon Mar 25 14:00:49 2024 -0400
@@ -35,7 +35,6 @@
 #  include "config.h"
 #endif
 
-#include <cassert>
 #include <cstdio>
 #include <cstdlib>
 
--- a/liboctave/array/Array-base.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/array/Array-base.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -35,6 +35,7 @@
 
 #include "Array-util.h"
 #include "Array.h"
+#include "lo-error.h"
 #include "lo-mappers.h"
 #include "oct-locbuf.h"
 
@@ -325,7 +326,7 @@
     : m_n (dv.ndims ()), m_top (0), m_dim (new octave_idx_type [2*m_n]),
       m_stride (m_dim + m_n), m_use_blk (false)
   {
-    assert (m_n == perm.numel ());
+    liboctave_panic_unless (m_n == perm.numel ());
 
     // Get cumulative dimensions.
     OCTAVE_LOCAL_BUFFER (octave_idx_type, cdim, m_n+1);
@@ -535,7 +536,7 @@
     : m_n (ia.numel ()), m_top (0), m_dim (new octave_idx_type [2*m_n]),
       m_cdim (m_dim + m_n), m_idx (new octave::idx_vector [m_n])
   {
-    assert (m_n > 0 && dv.ndims () == std::max (m_n, static_cast<octave_idx_type> (2)));
+    liboctave_panic_unless (m_n > 0 && dv.ndims () == std::max (m_n, static_cast<octave_idx_type> (2)));
 
     m_dim[0] = dv(0);
     m_cdim[0] = 1;
@@ -652,7 +653,7 @@
     : m_cext (nullptr), m_sext (nullptr), m_dext (nullptr), m_n (0)
   {
     int l = ndv.ndims ();
-    assert (odv.ndims () == l);
+    liboctave_panic_unless (odv.ndims () == l);
     octave_idx_type ld = 1;
     int i = 0;
     for (; i < l-1 && ndv(i) == odv(i); i++) ld *= ndv(i);
@@ -1644,7 +1645,7 @@
 Array<T, Alloc>
 Array<T, Alloc>::transpose () const
 {
-  assert (ndims () == 2);
+  liboctave_panic_unless (ndims () == 2);
 
   octave_idx_type nr = dim1 ();
   octave_idx_type nc = dim2 ();
@@ -1687,7 +1688,7 @@
 Array<T, Alloc>
 Array<T, Alloc>::hermitian (T (*fcn) (const T&)) const
 {
-  assert (ndims () == 2);
+  liboctave_panic_unless (ndims () == 2);
 
   if (! fcn)
     fcn = no_op_fcn<T>;
--- a/liboctave/array/Array-util.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/array/Array-util.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -264,7 +264,7 @@
 
   int n = ra_idx.numel ();
 
-  assert (n == dimensions.ndims ());
+  liboctave_panic_unless (n == dimensions.ndims ());
 
   retval.resize (n);
 
@@ -337,7 +337,7 @@
 
   int n = frozen_lengths.ndims ();
 
-  assert (idx_n == n);
+  liboctave_panic_unless (idx_n == n);
 
   for (octave_idx_type i = 0; i < n; i++)
     {
@@ -394,7 +394,7 @@
   for (int i = 0; i < n_dims; i++)
     retval(i) = 0;
 
-  assert (idx > 0 || idx < dims.numel ());
+  liboctave_panic_unless (idx > 0 || idx < dims.numel ());
 
   for (octave_idx_type i = 0; i < idx; i++)
     increment_index (retval, dims);
--- a/liboctave/array/Array.h	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/array/Array.h	Mon Mar 25 14:00:49 2024 -0400
@@ -28,7 +28,6 @@
 
 #include "octave-config.h"
 
-#include <cassert>
 #include <cstddef>
 
 #include <algorithm>
--- a/liboctave/array/CSparse.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/array/CSparse.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -34,6 +34,7 @@
 #include <ostream>
 
 #include "quit.h"
+#include "lo-error.h"
 #include "lo-ieee.h"
 #include "lo-mappers.h"
 #include "f77-fcn.h"
@@ -626,7 +627,7 @@
         retval.xridx (q) = j;
         retval.xdata (q) = conj (data (k));
       }
-  assert (nnz () == retval.xcidx (nr));
+  liboctave_panic_unless (nnz () == retval.xcidx (nr));
   // retval.xcidx[1:nr] holds row entry *end* offsets for rows 0:(nr-1)
   // and retval.xcidx[0:(nr-1)] holds their row entry *start* offsets
 
--- a/liboctave/array/DiagArray2.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/array/DiagArray2.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,8 +27,6 @@
 // C++ source files that should have included config.h before including
 // this file.
 
-#include <cassert>
-
 #include <algorithm>
 
 #include "DiagArray2.h"
--- a/liboctave/array/DiagArray2.h	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/array/DiagArray2.h	Mon Mar 25 14:00:49 2024 -0400
@@ -28,7 +28,6 @@
 
 #include "octave-config.h"
 
-#include <cassert>
 #include <cstdlib>
 
 #include "Array.h"
--- a/liboctave/array/Sparse.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/array/Sparse.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,7 +27,6 @@
 // C++ source files that should have included config.h before including
 // this file.
 
-#include <cassert>
 #include <cinttypes>
 
 #include <algorithm>
@@ -1139,7 +1138,7 @@
 Sparse<T, Alloc>
 Sparse<T, Alloc>::transpose () const
 {
-  assert (ndims () == 2);
+  liboctave_panic_unless (ndims () == 2);
 
   octave_idx_type nr = rows ();
   octave_idx_type nc = cols ();
@@ -1165,7 +1164,7 @@
         retval.xridx (q) = j;
         retval.xdata (q) = data (k);
       }
-  assert (nnz () == retval.xcidx (nr));
+  liboctave_panic_unless (nnz () == retval.xcidx (nr));
   // retval.xcidx[1:nr] holds row entry *end* offsets for rows 0:(nr-1)
   // and retval.xcidx[0:(nr-1)] holds their row entry *start* offsets
 
@@ -1199,7 +1198,7 @@
 {
   Sparse<T, Alloc> retval;
 
-  assert (ndims () == 2);
+  liboctave_panic_unless (ndims () == 2);
 
   octave_idx_type nr = dim1 ();
   octave_idx_type nc = dim2 ();
@@ -1300,7 +1299,7 @@
 Sparse<T, Alloc>::delete_elements (const octave::idx_vector& idx_i,
                                    const octave::idx_vector& idx_j)
 {
-  assert (ndims () == 2);
+  liboctave_panic_unless (ndims () == 2);
 
   octave_idx_type nr = dim1 ();
   octave_idx_type nc = dim2 ();
@@ -1435,7 +1434,7 @@
 {
   Sparse<T, Alloc> retval;
 
-  assert (ndims () == 2);
+  liboctave_panic_unless (ndims () == 2);
 
   octave_idx_type nr = dim1 ();
   octave_idx_type nc = dim2 ();
@@ -1638,7 +1637,7 @@
 {
   Sparse<T, Alloc> retval;
 
-  assert (ndims () == 2);
+  liboctave_panic_unless (ndims () == 2);
 
   octave_idx_type nr = dim1 ();
   octave_idx_type nc = dim2 ();
@@ -1883,7 +1882,7 @@
 {
   Sparse<T, Alloc> retval;
 
-  assert (ndims () == 2);
+  liboctave_panic_unless (ndims () == 2);
 
   octave_idx_type nr = dim1 ();
   octave_idx_type nc = dim2 ();
@@ -2048,7 +2047,7 @@
 {
   Sparse<T, Alloc> retval;
 
-  assert (ndims () == 2);
+  liboctave_panic_unless (ndims () == 2);
 
   octave_idx_type nr = dim1 ();
   octave_idx_type nc = dim2 ();
@@ -2142,7 +2141,7 @@
                   mx_inline_add (ub - lb, cidx () + lb + 1, rhs.cidx () + 1,
                                  li);
 
-                  assert (nnz () == new_nz);
+                  liboctave_panic_unless (nnz () == new_nz);
                 }
               else
                 {
@@ -2170,7 +2169,7 @@
                   mx_inline_add (nc - ub, cidx () + ub + 1,
                                  tmp.cidx () + ub + 1, new_nz - nz);
 
-                  assert (nnz () == new_nz);
+                  liboctave_panic_unless (nnz () == new_nz);
                 }
             }
           else if (idx_j.is_range () && idx_j.increment () == -1)
@@ -2755,7 +2754,7 @@
         break;
       }
     default:
-      assert (false);
+      liboctave_panic_impossible ();
     }
 
   return retval;
--- a/liboctave/array/Sparse.h	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/array/Sparse.h	Mon Mar 25 14:00:49 2024 -0400
@@ -28,7 +28,6 @@
 
 #include "octave-config.h"
 
-#include <cassert>
 #include <cstddef>
 
 #include <algorithm>
--- a/liboctave/array/dim-vector.h	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/array/dim-vector.h	Mon Mar 25 14:00:49 2024 -0400
@@ -30,8 +30,6 @@
 
 #include "octave-config.h"
 
-#include <cassert>
-
 #include <algorithm>
 #include <initializer_list>
 #include <string>
--- a/liboctave/array/idx-vector.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/array/idx-vector.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -1030,7 +1030,7 @@
 
   idx_vector_rep *r = dynamic_cast<idx_vector_rep *> (m_rep);
 
-  assert (r != nullptr);
+  liboctave_panic_unless (r != nullptr);
 
   return r->get_data ();
 }
@@ -1088,7 +1088,7 @@
       break;
 
     default:
-      assert (false);
+      liboctave_panic_impossible ();
       break;
     }
 }
@@ -1156,7 +1156,7 @@
 idx_vector
 idx_vector::inverse_permutation (octave_idx_type n) const
 {
-  assert (n == length (n));
+  liboctave_panic_unless (n == length (n));
 
   idx_vector retval;
 
@@ -1252,7 +1252,7 @@
       break;
 
     default:
-      assert (false);
+      liboctave_panic_impossible ();
       break;
     }
 }
--- a/liboctave/array/idx-vector.h	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/array/idx-vector.h	Mon Mar 25 14:00:49 2024 -0400
@@ -28,7 +28,6 @@
 
 #include "octave-config.h"
 
-#include <cassert>
 #include <cstring>
 
 #include <algorithm>
@@ -37,6 +36,7 @@
 
 #include "Array-fwd.h"
 #include "dim-vector.h"
+#include "lo-error.h"
 #include "oct-inttypes.h"
 #include "oct-refcount.h"
 #include "Sparse-fwd.h"
@@ -638,7 +638,7 @@
         break;
 
       default:
-        assert (false);
+        liboctave_panic_impossible ();
         break;
       }
 
@@ -710,7 +710,7 @@
         break;
 
       default:
-        assert (false);
+        liboctave_panic_impossible ();
         break;
       }
 
@@ -782,7 +782,7 @@
         break;
 
       default:
-        assert (false);
+        liboctave_panic_impossible ();
         break;
       }
 
@@ -848,7 +848,7 @@
         break;
 
       default:
-        assert (false);
+        liboctave_panic_impossible ();
         break;
       }
 
@@ -934,7 +934,7 @@
         break;
 
       default:
-        assert (false);
+        liboctave_panic_impossible ();
         break;
       }
 
--- a/liboctave/numeric/CollocWt.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/numeric/CollocWt.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,7 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <cassert>
 #include <cmath>
 
 #include <limits>
@@ -152,12 +151,12 @@
        double alpha, double beta, double *dif1, double *dif2,
        double *dif3, double *root)
 {
-  assert (n0 == 0 || n0 == 1);
-  assert (n1 == 0 || n1 == 1);
+  liboctave_panic_unless (n0 == 0 || n0 == 1);
+  liboctave_panic_unless (n1 == 0 || n1 == 1);
 
   octave_idx_type nt = n + n0 + n1;
 
-  assert (nt >= 1);
+  liboctave_panic_unless (nt >= 1);
 
   // -- first evaluation of coefficients in recursion formulas.
   // -- recursion coefficients are stored in dif1 and dif2.
@@ -314,17 +313,17 @@
        octave_idx_type i, octave_idx_type id, double *dif1,
        double *dif2, double *dif3, double *root, double *vect)
 {
-  assert (n0 == 0 || n0 == 1);
-  assert (n1 == 0 || n1 == 1);
+  liboctave_panic_unless (n0 == 0 || n0 == 1);
+  liboctave_panic_unless (n1 == 0 || n1 == 1);
 
   octave_idx_type nt = n + n0 + n1;
 
-  assert (nt >= 1);
+  liboctave_panic_unless (nt >= 1);
 
-  assert (id == 1 || id == 2 || id == 3);
+  liboctave_panic_unless (id == 1 || id == 2 || id == 3);
 
   if (id != 3)
-    assert (i >= 0 && i < nt);
+    liboctave_panic_unless (i >= 0 && i < nt);
 
   // Evaluate discretization matrices and Gaussian quadrature weights.
   // Quadrature weights are normalized to sum to one.
--- a/liboctave/numeric/Quad.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/numeric/Quad.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,8 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <cassert>
-
 #include "Array.h"
 #include "Quad.h"
 #include "f77-fcn.h"
@@ -172,7 +170,7 @@
       break;
 
     default:
-      assert (0);
+      liboctave_panic_impossible ();
       break;
     }
 
@@ -289,7 +287,7 @@
       break;
 
     default:
-      assert (0);
+      liboctave_panic_impossible ();
       break;
     }
 
--- a/liboctave/numeric/oct-rand.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/numeric/oct-rand.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,7 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <cassert>
 #include <cstdint>
 
 #include <limits>
@@ -98,7 +97,7 @@
 static int32_t
 force_to_fit_range (int32_t i, int32_t lo, int32_t hi)
 {
-  assert (hi > lo && lo >= 0);
+  liboctave_panic_unless (hi > lo && lo >= 0);
 
   i = (i > 0 ? i : -i);
 
--- a/liboctave/numeric/qrp.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/numeric/qrp.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,8 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <cassert>
-
 #include <algorithm>
 
 #include "Array.h"
@@ -54,7 +52,7 @@
 void
 qrp<Matrix>::init (const Matrix& a, type qr_type)
 {
-  assert (qr_type != qr<Matrix>::raw);
+  liboctave_panic_if (qr_type == qr<Matrix>::raw);
 
   F77_INT m = to_f77_int (a.rows ());
   F77_INT n = to_f77_int (a.cols ());
@@ -125,7 +123,7 @@
 void
 qrp<FloatMatrix>::init (const FloatMatrix& a, type qr_type)
 {
-  assert (qr_type != qr<FloatMatrix>::raw);
+  liboctave_panic_if (qr_type == qr<FloatMatrix>::raw);
 
   F77_INT m = to_f77_int (a.rows ());
   F77_INT n = to_f77_int (a.cols ());
@@ -196,7 +194,7 @@
 void
 qrp<ComplexMatrix>::init (const ComplexMatrix& a, type qr_type)
 {
-  assert (qr_type != qr<ComplexMatrix>::raw);
+  liboctave_panic_if (qr_type == qr<ComplexMatrix>::raw);
 
   F77_INT m = to_f77_int (a.rows ());
   F77_INT n = to_f77_int (a.cols ());
@@ -275,7 +273,7 @@
 void
 qrp<FloatComplexMatrix>::init (const FloatComplexMatrix& a, type qr_type)
 {
-  assert (qr_type != qr<FloatComplexMatrix>::raw);
+  liboctave_panic_if (qr_type == qr<FloatComplexMatrix>::raw);
 
   F77_INT m = to_f77_int (a.rows ());
   F77_INT n = to_f77_int (a.cols ());
--- a/liboctave/numeric/svd.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/numeric/svd.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -27,8 +27,6 @@
 #  include "config.h"
 #endif
 
-#include <cassert>
-
 #include <algorithm>
 #include <unordered_map>
 
@@ -774,7 +772,7 @@
            work, lwork, info);
   else if (m_driver == svd::Driver::GESDD)
     {
-      assert (jobu == jobv);
+      liboctave_panic_unless (jobu == jobv);
       char jobz = jobu;
 
       std::vector<F77_INT> iwork (8 * std::min (m, n));
--- a/liboctave/operators/Sparse-perm-op-defs.h	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/operators/Sparse-perm-op-defs.h	Mon Mar 25 14:00:49 2024 -0400
@@ -112,7 +112,7 @@
           r.xdata (k) = a.data (k_src);
         }
     }
-  assert (k_src == nent);
+  liboctave_panic_unless (k_src == nent);
 
   return r;
 }
@@ -132,7 +132,7 @@
       const octave_idx_type j_src = pcol[j];
       r.xcidx (j+1) = r.xcidx (j) + (a.cidx (j_src+1) - a.cidx (j_src));
     }
-  assert (r.xcidx (nc) == nent);
+  liboctave_panic_unless (r.xcidx (nc) == nent);
 
   octave_idx_type k = 0;
   for (octave_idx_type j = 0; j < nc; ++j)
@@ -147,7 +147,7 @@
           r.xdata (k) = a.data (k_src);
         }
     }
-  assert (k == nent);
+  liboctave_panic_unless (k == nent);
 
   return r;
 }
--- a/liboctave/util/lo-error.h	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/util/lo-error.h	Mon Mar 25 14:00:49 2024 -0400
@@ -81,6 +81,24 @@
 extern OCTAVE_API void
 set_liboctave_warning_with_id_handler (liboctave_warning_with_id_handler f);
 
+// To allow the __FILE__ and __LINE__ macros to work as expected, the
+// liboctave_panic_impossible, liboctave_panic_if, and
+// liboctave_panic_unless symbols must be defined as macros.
+
+#define liboctave_panic_impossible() (*current_liboctave_error_handler) ("impossible state reached in file '%s' at line %d", __FILE__, __LINE__)
+
+#if defined (NDEBUG)
+#  define liboctave_panic_if(cond)
+#else
+#  define liboctave_panic_if(cond) do { if (cond) liboctave_panic_impossible (); } while (0)
+#endif
+
+#if defined (NDEBUG)
+#  define liboctave_panic_unless(cond)
+#else
+#  define liboctave_panic_unless(cond) liboctave_panic_if (! (cond))
+#endif
+
 #if defined (__cplusplus)
 }
 #endif
--- a/liboctave/util/oct-sort.cc	Sun Mar 24 16:53:18 2024 -0400
+++ b/liboctave/util/oct-sort.cc	Mon Mar 25 14:00:49 2024 -0400
@@ -107,7 +107,6 @@
 // C++ source files that should have included config.h before including
 // this file.
 
-#include <cassert>
 #include <algorithm>
 #include <cstring>
 #include <stack>
@@ -1437,7 +1436,7 @@
               n = force;
             }
           /* Push run onto m_pending-runs stack, and maybe merge. */
-          assert (m_ms->m_n < MAX_MERGE_PENDING);
+          liboctave_panic_unless (m_ms->m_n < MAX_MERGE_PENDING);
           m_ms->m_pending[m_ms->m_n].m_base = lo;
           m_ms->m_pending[m_ms->m_n].m_len = n;
           m_ms->m_n++;
@@ -1497,7 +1496,7 @@
               n = force;
             }
           /* Push run onto m_pending-runs stack, and maybe merge. */
-          assert (m_ms->m_n < MAX_MERGE_PENDING);
+          liboctave_panic_unless (m_ms->m_n < MAX_MERGE_PENDING);
           m_ms->m_pending[m_ms->m_n].m_base = lo;
           m_ms->m_pending[m_ms->m_n].m_len = n;
           m_ms->m_n++;
@@ -1630,7 +1629,7 @@
       octave_idx_type ofs = runs.top ().ofs;
       octave_idx_type nel = runs.top ().nel;
       runs.pop ();
-      assert (nel > 1);
+      liboctave_panic_unless (nel > 1);
 
       T *lbuf = buf + ofs;
       const T *ldata = data + rows*col;
@@ -1705,7 +1704,7 @@
       if (lo < lastrow)
         {
           // Not the final column.
-          assert (n > 1);
+          liboctave_panic_unless (n > 1);
           const T *hi = lo + n;
           const T *lst = lo;
           for (lo++; lo < hi; lo++)