changeset 23391:209e749363a2

safe cast between SuiteSparse_long and octave_idx_type pointers (bug #50510) * oct-sparse.cc: New file. * liboctave/util/module.mk: Update. * oct-sparse.h, oct-sparse.cc (octave::suitesparse_integer): New typedef. (octave::to_suitesparse_intptr, octave::to_octave_idx_type_ptr): New functions. * amd.cc, ccolamd.cc, colamd.cc, dmperm.cc, symbfact.cc, CSparse.cc, dSparse.cc, sparse-dmsolve.cc, sparse-lu.cc, sparse-qr.cc: Use new functions and typedef to avoid conflicts between pointers to octave_idx_type and SuiteSparse_long on systems where they are equivalent types but have incompatible definitions (long long int * vs. long int *, for example, when both are 64-bits wide).
author John W. Eaton <jwe@octave.org>
date Wed, 12 Apr 2017 16:29:50 -0400
parents 1ae9f4c1f48a
children 77a7f2fecd74
files libinterp/dldfcn/amd.cc libinterp/dldfcn/ccolamd.cc libinterp/dldfcn/colamd.cc libinterp/dldfcn/dmperm.cc libinterp/dldfcn/symbfact.cc liboctave/array/CSparse.cc liboctave/array/dSparse.cc liboctave/numeric/sparse-dmsolve.cc liboctave/numeric/sparse-lu.cc liboctave/numeric/sparse-qr.cc liboctave/util/module.mk liboctave/util/oct-sparse.cc liboctave/util/oct-sparse.h
diffstat 13 files changed, 288 insertions(+), 109 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/amd.cc	Wed Apr 12 13:38:01 2017 -0400
+++ b/libinterp/dldfcn/amd.cc	Wed Apr 12 16:29:50 2017 -0400
@@ -84,7 +84,7 @@
     print_usage ();
 
   octave_idx_type n_row, n_col;
-  const octave_idx_type *ridx, *cidx;
+  const octave::suitesparse_integer *ridx, *cidx;
   SparseMatrix sm;
   SparseComplexMatrix scm;
 
@@ -95,16 +95,16 @@
           scm = args(0).sparse_complex_matrix_value ();
           n_row = scm.rows ();
           n_col = scm.cols ();
-          ridx = scm.xridx ();
-          cidx = scm.xcidx ();
+          ridx = octave::to_suitesparse_intptr (scm.xridx ());
+          cidx = octave::to_suitesparse_intptr (scm.xcidx ());
         }
       else
         {
           sm = args(0).sparse_matrix_value ();
           n_row = sm.rows ();
           n_col = sm.cols ();
-          ridx = sm.xridx ();
-          cidx = sm.xcidx ();
+          ridx = octave::to_suitesparse_intptr (sm.xridx ());
+          cidx = octave::to_suitesparse_intptr (sm.xcidx ());
         }
     }
   else
@@ -116,8 +116,8 @@
 
       n_row = sm.rows ();
       n_col = sm.cols ();
-      ridx = sm.xridx ();
-      cidx = sm.xcidx ();
+      ridx = octave::to_suitesparse_intptr (sm.xridx ());
+      cidx = octave::to_suitesparse_intptr (sm.xcidx ());
     }
 
   if (n_row != n_col)
@@ -140,7 +140,7 @@
         Control[AMD_AGGRESSIVE] = tmp.double_value ();
     }
 
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, P, n_col);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, P, n_col);
   Matrix xinfo (AMD_INFO, 1);
   double *Info = xinfo.fortran_vec ();
 
@@ -152,8 +152,8 @@
   SUITESPARSE_ASSIGN_FPTR (realloc_func, amd_realloc, realloc);
   SUITESPARSE_ASSIGN_FPTR (printf_func, amd_printf, printf);
 
-  octave_idx_type result = AMD_NAME (_order) (n_col, cidx, ridx, P,
-                                              Control, Info);
+  octave_idx_type result = AMD_NAME (_order) (n_col, cidx, ridx, P, Control,
+                                              Info);
 
   if (result == AMD_OUT_OF_MEMORY)
     error ("amd: out of memory");
--- a/libinterp/dldfcn/ccolamd.cc	Wed Apr 12 13:38:01 2017 -0400
+++ b/libinterp/dldfcn/ccolamd.cc	Wed Apr 12 16:29:50 2017 -0400
@@ -248,31 +248,31 @@
     }
 
   // Allocate workspace for ccolamd
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, p, n_col+1);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, p, n_col+1);
   for (octave_idx_type i = 0; i < n_col+1; i++)
     p[i] = cidx[i];
 
   octave_idx_type Alen = CCOLAMD_NAME (_recommended) (nnz, n_row, n_col);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, A, Alen);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, A, Alen);
   for (octave_idx_type i = 0; i < nnz; i++)
     A[i] = ridx[i];
 
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, CCOLAMD_STATS);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, stats, CCOLAMD_STATS);
 
   if (nargin > 2)
     {
       NDArray in_cmember = args(2).array_value ();
       octave_idx_type cslen = in_cmember.numel ();
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, cmember, cslen);
+      OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, cmember, cslen);
       for (octave_idx_type i = 0; i < cslen; i++)
         // convert cmember from 1-based to 0-based
-        cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
+        cmember[i] = static_cast<octave::suitesparse_integer>(in_cmember(i) - 1);
 
       if (cslen != n_col)
         error ("ccolamd: CMEMBER must be of length equal to #cols of A");
 
       // Order the columns (destroys A)
-      if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats, cmember))
+      if (! CCOLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats,cmember))
         {
           CCOLAMD_NAME (_report) (stats);
 
@@ -491,14 +491,14 @@
     err_square_matrix_required ("csymamd", "S");
 
   // Allocate workspace for symamd
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, perm, n_col+1);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, CCOLAMD_STATS);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, perm, n_col+1);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, stats, CCOLAMD_STATS);
 
   if (nargin > 2)
     {
       NDArray in_cmember = args(2).array_value ();
       octave_idx_type cslen = in_cmember.numel ();
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, cmember, cslen);
+      OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, cmember, cslen);
       for (octave_idx_type i = 0; i < cslen; i++)
         // convert cmember from 1-based to 0-based
         cmember[i] = static_cast<octave_idx_type>(in_cmember(i) - 1);
@@ -506,8 +506,10 @@
       if (cslen != n_col)
         error ("csymamd: CMEMBER must be of length equal to #cols of A");
 
-      if (! CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats,
-                             &calloc, &free, cmember, -1))
+      if (! CSYMAMD_NAME () (n_col,
+                             octave::to_suitesparse_intptr (ridx),
+                             octave::to_suitesparse_intptr (cidx),
+                             perm, knobs, stats, &calloc, &free, cmember, -1))
         {
           CSYMAMD_NAME (_report)(stats);
 
@@ -516,8 +518,10 @@
     }
   else
     {
-      if (! CSYMAMD_NAME () (n_col, ridx, cidx, perm, knobs, stats,
-                             &calloc, &free, 0, -1))
+      if (! CSYMAMD_NAME () (n_col,
+                             octave::to_suitesparse_intptr (ridx),
+                             octave::to_suitesparse_intptr (cidx),
+                             perm, knobs, stats, &calloc, &free, 0, -1))
         {
           CSYMAMD_NAME (_report)(stats);
 
--- a/libinterp/dldfcn/colamd.cc	Wed Apr 12 13:38:01 2017 -0400
+++ b/libinterp/dldfcn/colamd.cc	Wed Apr 12 16:29:50 2017 -0400
@@ -370,17 +370,17 @@
     }
 
   // Allocate workspace for colamd
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, p, n_col+1);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, p, n_col+1);
   for (octave_idx_type i = 0; i < n_col+1; i++)
     p[i] = cidx[i];
 
   octave_idx_type Alen = COLAMD_NAME (_recommended) (nnz, n_row, n_col);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, A, Alen);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, A, Alen);
   for (octave_idx_type i = 0; i < nnz; i++)
     A[i] = ridx[i];
 
   // Order the columns (destroys A)
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, COLAMD_STATS);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, stats, COLAMD_STATS);
   if (! COLAMD_NAME () (n_row, n_col, Alen, A, p, knobs, stats))
     {
       COLAMD_NAME (_report)(stats);
@@ -580,8 +580,10 @@
 
   // Allocate workspace for symamd
   OCTAVE_LOCAL_BUFFER (octave_idx_type, perm, n_col+1);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, stats, COLAMD_STATS);
-  if (! SYMAMD_NAME () (n_col, ridx, cidx, perm,
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, stats, COLAMD_STATS);
+  if (! SYMAMD_NAME () (n_col, octave::to_suitesparse_intptr (ridx),
+                        octave::to_suitesparse_intptr (cidx),
+                        octave::to_suitesparse_intptr (perm),
                         knobs, stats, &calloc, &free))
     {
       SYMAMD_NAME (_report)(stats);
--- a/libinterp/dldfcn/dmperm.cc	Wed Apr 12 13:38:01 2017 -0400
+++ b/libinterp/dldfcn/dmperm.cc	Wed Apr 12 16:29:50 2017 -0400
@@ -45,7 +45,7 @@
 #if defined (HAVE_CXSPARSE)
 
 static RowVector
-put_int (octave_idx_type *p, octave_idx_type n)
+put_int (octave::suitesparse_integer *p, octave_idx_type n)
 {
   RowVector ret (n);
   for (octave_idx_type i = 0; i < n; i++)
@@ -71,20 +71,20 @@
     {
       m = arg.sparse_matrix_value ();
       csm.nzmax = m.nnz ();
-      csm.p = m.xcidx ();
-      csm.i = m.xridx ();
+      csm.p = octave::to_suitesparse_intptr (m.xcidx ());
+      csm.i = octave::to_suitesparse_intptr (m.xridx ());
     }
   else
     {
       cm = arg.sparse_complex_matrix_value ();
       csm.nzmax = cm.nnz ();
-      csm.p = cm.xcidx ();
-      csm.i = cm.xridx ();
+      csm.p = octave::to_suitesparse_intptr (cm.xcidx ());
+      csm.i = octave::to_suitesparse_intptr (cm.xridx ());
     }
 
   if (nargout <= 1 || rank)
     {
-      octave_idx_type *jmatch = CXSPARSE_NAME (_maxtrans) (&csm, 0);
+      octave::suitesparse_integer *jmatch = CXSPARSE_NAME (_maxtrans) (&csm, 0);
       if (rank)
         {
           octave_idx_type r = 0;
--- a/libinterp/dldfcn/symbfact.cc	Wed Apr 12 13:38:01 2017 -0400
+++ b/libinterp/dldfcn/symbfact.cc	Wed Apr 12 16:29:50 2017 -0400
@@ -198,10 +198,10 @@
   if (A->stype && A->nrow != A->ncol)
     err_square_matrix_required ("symbfact", "S");
 
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, Parent, n);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, Post, n);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, ColCount, n);
-  OCTAVE_LOCAL_BUFFER (octave_idx_type, First, n);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, Parent, n);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, Post, n);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, ColCount, n);
+  OCTAVE_LOCAL_BUFFER (octave::suitesparse_integer, First, n);
   OCTAVE_LOCAL_BUFFER (octave_idx_type, Level, n);
 
   cholmod_common Common;
@@ -255,8 +255,8 @@
       goto cleanup;
     }
 
-  CHOLMOD_NAME(rowcolcounts) (Alo, 0, 0, Parent, Post, 0,
-                              ColCount, First, Level, cm);
+  CHOLMOD_NAME(rowcolcounts) (Alo, 0, 0, Parent, Post, 0, ColCount, First,
+                              octave::to_suitesparse_intptr (Level), cm);
 
   if (cm->status < CHOLMOD_OK)
     {
@@ -307,7 +307,7 @@
       L.xcidx(n) = lnz;
 
       // create a copy of the column pointers
-      octave_idx_type *W = First;
+      octave::suitesparse_integer *W = First;
       for (octave_idx_type j = 0 ; j < n ; j++)
         W[j] = L.xcidx (j);
 
--- a/liboctave/array/CSparse.cc	Wed Apr 12 13:38:01 2017 -0400
+++ b/liboctave/array/CSparse.cc	Wed Apr 12 16:29:50 2017 -0400
@@ -1114,16 +1114,20 @@
       const octave_idx_type *Ai = ridx ();
       const Complex *Ax = data ();
 
-      UMFPACK_ZNAME (report_matrix) (nr, nc, Ap, Ai,
+      UMFPACK_ZNAME (report_matrix) (nr, nc,
+                                     octave::to_suitesparse_intptr (Ap),
+                                     octave::to_suitesparse_intptr (Ai),
                                      reinterpret_cast<const double *> (Ax),
                                      0, 1, control);
 
       void *Symbolic;
       Matrix Info (1, UMFPACK_INFO);
       double *info = Info.fortran_vec ();
-      int status = UMFPACK_ZNAME (qsymbolic)
-                   (nr, nc, Ap, Ai, reinterpret_cast<const double *> (Ax), 0,
-                    0, &Symbolic, control, info);
+      int status = UMFPACK_ZNAME (qsymbolic) (nr, nc,
+                                              octave::to_suitesparse_intptr (Ap),
+                                              octave::to_suitesparse_intptr (Ai),
+                                              reinterpret_cast<const double *> (Ax),
+                                              0, 0, &Symbolic, control, info);
 
       if (status < 0)
         {
@@ -1141,7 +1145,8 @@
 
           void *Numeric;
           status
-            = UMFPACK_ZNAME (numeric) (Ap, Ai,
+            = UMFPACK_ZNAME (numeric) (octave::to_suitesparse_intptr (Ap),
+                                       octave::to_suitesparse_intptr (Ai),
                                        reinterpret_cast<const double *> (Ax),
                                        0, Symbolic, &Numeric, control, info);
           UMFPACK_ZNAME (free_symbolic) (&Symbolic);
@@ -5547,14 +5552,18 @@
   octave_idx_type nr = rows ();
   octave_idx_type nc = cols ();
 
-  UMFPACK_ZNAME (report_matrix) (nr, nc, Ap, Ai,
+  UMFPACK_ZNAME (report_matrix) (nr, nc,
+                                 octave::to_suitesparse_intptr (Ap),
+                                 octave::to_suitesparse_intptr (Ai),
                                  reinterpret_cast<const double *> (Ax),
                                  0, 1, control);
 
   void *Symbolic;
   Info = Matrix (1, UMFPACK_INFO);
   double *info = Info.fortran_vec ();
-  int status = UMFPACK_ZNAME (qsymbolic) (nr, nc, Ap, Ai,
+  int status = UMFPACK_ZNAME (qsymbolic) (nr, nc,
+                                          octave::to_suitesparse_intptr (Ap),
+                                          octave::to_suitesparse_intptr (Ai),
                                           reinterpret_cast<const double *> (Ax),
                                           0, 0, &Symbolic, control, info);
 
@@ -5574,7 +5583,8 @@
     {
       UMFPACK_ZNAME (report_symbolic) (Symbolic, control);
 
-      status = UMFPACK_ZNAME (numeric) (Ap, Ai,
+      status = UMFPACK_ZNAME (numeric) (octave::to_suitesparse_intptr (Ap),
+                                        octave::to_suitesparse_intptr (Ai),
                                         reinterpret_cast<const double *> (Ax),
                                         0, Symbolic, &Numeric, control, info);
       UMFPACK_ZNAME (free_symbolic) (&Symbolic);
@@ -5823,8 +5833,9 @@
               for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr)
                 {
 #if defined (UMFPACK_SEPARATE_SPLIT)
-                  status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap,
-                                                  Ai,
+                  status = UMFPACK_ZNAME (solve) (UMFPACK_A,
+                                                  octave::to_suitesparse_intptr (Ap),
+                                                  octave::to_suitesparse_intptr (Ai),
                                                   reinterpret_cast<const double *> (Ax),
                                                   0,
                                                   reinterpret_cast<double *> (&Xx[iidx]),
@@ -5835,8 +5846,9 @@
                   for (octave_idx_type i = 0; i < b_nr; i++)
                     Bz[i] = b.elem (i, j);
 
-                  status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap,
-                                                  Ai,
+                  status = UMFPACK_ZNAME (solve) (UMFPACK_A,
+                                                  octave::to_suitesparse_intptr (Ap),
+                                                  octave::to_suitesparse_intptr (Ai),
                                                   reinterpret_cast<const double *> (Ax),
                                                   0,
                                                   reinterpret_cast<double *> (&Xx[iidx]),
@@ -6101,8 +6113,9 @@
                   for (octave_idx_type i = 0; i < b_nr; i++)
                     Bx[i] = b.elem (i, j);
 
-                  status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap,
-                                                  Ai,
+                  status = UMFPACK_ZNAME (solve) (UMFPACK_A,
+                                                  octave::to_suitesparse_intptr (Ap),
+                                                  octave::to_suitesparse_intptr (Ai),
                                                   reinterpret_cast<const double *> (Ax),
                                                   0,
                                                   reinterpret_cast<double *> (Xx),
@@ -6113,7 +6126,9 @@
                   for (octave_idx_type i = 0; i < b_nr; i++)
                     Bz[i] = b.elem (i, j);
 
-                  status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap, Ai,
+                  status = UMFPACK_ZNAME (solve) (UMFPACK_A,
+                                                  octave::to_suitesparse_intptr (Ap),
+                                                  octave::to_suitesparse_intptr (Ai),
                                                   reinterpret_cast<const double *> (Ax),
                                                   0,
                                                   reinterpret_cast<double *> (Xx),
@@ -6365,7 +6380,9 @@
               for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr)
                 {
                   status =
-                    UMFPACK_ZNAME (solve) (UMFPACK_A, Ap, Ai,
+                    UMFPACK_ZNAME (solve) (UMFPACK_A,
+                                           octave::to_suitesparse_intptr (Ap),
+                                           octave::to_suitesparse_intptr (Ai),
                                            reinterpret_cast<const double *> (Ax),
                                            0,
                                            reinterpret_cast<double *> (&Xx[iidx]),
@@ -6619,8 +6636,9 @@
                   for (octave_idx_type i = 0; i < b_nr; i++)
                     Bx[i] = b(i,j);
 
-                  status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap,
-                                                  Ai,
+                  status = UMFPACK_ZNAME (solve) (UMFPACK_A,
+                                                  octave::to_suitesparse_intptr (Ap),
+                                                  octave::to_suitesparse_intptr (Ai),
                                                   reinterpret_cast<const double *> (Ax),
                                                   0,
                                                   reinterpret_cast<double *> (Xx),
--- a/liboctave/array/dSparse.cc	Wed Apr 12 13:38:01 2017 -0400
+++ b/liboctave/array/dSparse.cc	Wed Apr 12 16:29:50 2017 -0400
@@ -1190,12 +1190,17 @@
       const octave_idx_type *Ai = ridx ();
       const double *Ax = data ();
 
-      UMFPACK_DNAME (report_matrix) (nr, nc, Ap, Ai, Ax, 1, control);
+      UMFPACK_DNAME (report_matrix) (nr, nc,
+                                     octave::to_suitesparse_intptr (Ap),
+                                     octave::to_suitesparse_intptr (Ai),
+                                     Ax, 1, control);
 
       void *Symbolic;
       Matrix Info (1, UMFPACK_INFO);
       double *info = Info.fortran_vec ();
-      int status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai,
+      int status = UMFPACK_DNAME (qsymbolic) (nr, nc,
+                                              octave::to_suitesparse_intptr (Ap),
+                                              octave::to_suitesparse_intptr (Ai),
                                               Ax, 0, &Symbolic, control, info);
 
       if (status < 0)
@@ -1213,7 +1218,9 @@
           UMFPACK_DNAME (report_symbolic) (Symbolic, control);
 
           void *Numeric;
-          status = UMFPACK_DNAME (numeric) (Ap, Ai, Ax, Symbolic,
+          status = UMFPACK_DNAME (numeric) (octave::to_suitesparse_intptr (Ap),
+                                            octave::to_suitesparse_intptr (Ai),
+                                            Ax, Symbolic,
                                             &Numeric, control, info);
           UMFPACK_DNAME (free_symbolic) (&Symbolic);
 
@@ -5735,13 +5742,18 @@
   octave_idx_type nr = rows ();
   octave_idx_type nc = cols ();
 
-  UMFPACK_DNAME (report_matrix) (nr, nc, Ap, Ai, Ax, 1, control);
+  UMFPACK_DNAME (report_matrix) (nr, nc,
+                                 octave::to_suitesparse_intptr (Ap),
+                                 octave::to_suitesparse_intptr (Ai),
+                                 Ax, 1, control);
 
   void *Symbolic;
   Info = Matrix (1, UMFPACK_INFO);
   double *info = Info.fortran_vec ();
-  int status = UMFPACK_DNAME (qsymbolic) (nr, nc, Ap, Ai, Ax, 0,
-                                          &Symbolic, control, info);
+  int status = UMFPACK_DNAME (qsymbolic) (nr, nc,
+                                          octave::to_suitesparse_intptr (Ap),
+                                          octave::to_suitesparse_intptr (Ai),
+                                          Ax, 0, &Symbolic, control, info);
 
   if (status < 0)
     {
@@ -5759,8 +5771,9 @@
     {
       UMFPACK_DNAME (report_symbolic) (Symbolic, control);
 
-      status = UMFPACK_DNAME (numeric) (Ap, Ai, Ax, Symbolic,
-                                        &Numeric, control, info);
+      status = UMFPACK_DNAME (numeric) (octave::to_suitesparse_intptr (Ap),
+                                        octave::to_suitesparse_intptr (Ai),
+                                        Ax, Symbolic, &Numeric, control, info);
       UMFPACK_DNAME (free_symbolic) (&Symbolic);
 
       if (calc_cond)
@@ -6001,10 +6014,11 @@
 
               for (octave_idx_type j = 0, iidx = 0; j < b_nc; j++, iidx += b_nr)
                 {
-                  status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap,
-                                                  Ai, Ax, &result[iidx],
-                                                  &Bx[iidx], Numeric, control,
-                                                  info);
+                  status = UMFPACK_DNAME (solve) (UMFPACK_A,
+                                                  octave::to_suitesparse_intptr (Ap),
+                                                  octave::to_suitesparse_intptr (Ai),
+                                                  Ax, &result[iidx], &Bx[iidx],
+                                                  Numeric, control, info);
                   if (status < 0)
                     {
                       UMFPACK_DNAME (report_status) (control, status);
@@ -6250,8 +6264,10 @@
                   for (octave_idx_type i = 0; i < b_nr; i++)
                     Bx[i] = b.elem (i, j);
 
-                  status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap,
-                                                  Ai, Ax, Xx, Bx, Numeric,
+                  status = UMFPACK_DNAME (solve) (UMFPACK_A,
+                                                  octave::to_suitesparse_intptr (Ap),
+                                                  octave::to_suitesparse_intptr (Ai),
+                                                  Ax, Xx, Bx, Numeric,
                                                   control, info);
                   if (status < 0)
                     {
@@ -6505,11 +6521,15 @@
                       Bz[i] = c.imag ();
                     }
 
-                  status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap,
-                                                  Ai, Ax, Xx, Bx, Numeric,
+                  status = UMFPACK_DNAME (solve) (UMFPACK_A,
+                                                  octave::to_suitesparse_intptr (Ap),
+                                                  octave::to_suitesparse_intptr (Ai),
+                                                  Ax, Xx, Bx, Numeric,
                                                   control, info);
                   int status2 = UMFPACK_DNAME (solve) (UMFPACK_A,
-                                                       Ap, Ai, Ax, Xz, Bz,
+                                                       octave::to_suitesparse_intptr (Ap),
+                                                       octave::to_suitesparse_intptr (Ai),
+                                                       Ax, Xz, Bz,
                                                        Numeric, control, info);
 
                   if (status < 0 || status2 < 0)
@@ -6767,11 +6787,15 @@
                       Bz[i] = c.imag ();
                     }
 
-                  status = UMFPACK_DNAME (solve) (UMFPACK_A, Ap,
-                                                  Ai, Ax, Xx, Bx, Numeric,
+                  status = UMFPACK_DNAME (solve) (UMFPACK_A,
+                                                  octave::to_suitesparse_intptr (Ap),
+                                                  octave::to_suitesparse_intptr (Ai),
+                                                  Ax, Xx, Bx, Numeric,
                                                   control, info);
                   int status2 = UMFPACK_DNAME (solve) (UMFPACK_A,
-                                                       Ap, Ai, Ax, Xz, Bz,
+                                                       octave::to_suitesparse_intptr (Ap),
+                                                       octave::to_suitesparse_intptr (Ai),
+                                                       Ax, Xz, Bz,
                                                        Numeric, control, info);
 
                   if (status < 0 || status2 < 0)
--- a/liboctave/numeric/sparse-dmsolve.cc	Wed Apr 12 13:38:01 2017 -0400
+++ b/liboctave/numeric/sparse-dmsolve.cc	Wed Apr 12 16:29:50 2017 -0400
@@ -389,12 +389,12 @@
 
       // Cast away const on A, with full knowledge that CSparse won't touch it.
       // Prevents the methods below making a copy of the data.
-      csm.p = const_cast<octave_idx_type *>(a.cidx ());
-      csm.i = const_cast<octave_idx_type *>(a.ridx ());
+      csm.p = const_cast<octave::suitesparse_integer *>(octave::to_suitesparse_intptr (a.cidx ()));
+      csm.i = const_cast<octave::suitesparse_integer *>(octave::to_suitesparse_intptr (a.ridx ()));
 
       CXSPARSE_DNAME (d) *dm = CXSPARSE_DNAME(_dmperm) (&csm, 0);
-      octave_idx_type *p = dm->p;
-      octave_idx_type *q = dm->q;
+      octave_idx_type *p = octave::to_octave_idx_type_ptr (dm->p);
+      octave_idx_type *q = octave::to_octave_idx_type_ptr (dm->q);
 
       OCTAVE_LOCAL_BUFFER (octave_idx_type, pinv, nr);
 
--- a/liboctave/numeric/sparse-lu.cc	Wed Apr 12 13:38:01 2017 -0400
+++ b/liboctave/numeric/sparse-lu.cc	Wed Apr 12 16:29:50 2017 -0400
@@ -150,10 +150,11 @@
     umfpack_get_lunz<double>
     (octave_idx_type *lnz, octave_idx_type *unz, void *Numeric)
     {
-      octave_idx_type ignore1, ignore2, ignore3;
+      suitesparse_integer ignore1, ignore2, ignore3;
 
-      return UMFPACK_DNAME (get_lunz) (lnz, unz, &ignore1, &ignore2,
-                                       &ignore3, Numeric);
+      return UMFPACK_DNAME (get_lunz) (to_suitesparse_intptr (lnz),
+                                       to_suitesparse_intptr (unz),
+                                       &ignore1, &ignore2, &ignore3, Numeric);
     }
 
     template <>
@@ -164,8 +165,14 @@
      octave_idx_type *p, octave_idx_type *q, double *Dx,
      octave_idx_type *do_recip, double *Rs, void *Numeric)
     {
-      return UMFPACK_DNAME (get_numeric) (Lp, Lj, Lx, Up, Ui, Ux, p, q, Dx,
-                                          do_recip, Rs, Numeric);
+      return UMFPACK_DNAME (get_numeric) (to_suitesparse_intptr (Lp),
+                                          to_suitesparse_intptr (Lj),
+                                          Lx, to_suitesparse_intptr (Up),
+                                          to_suitesparse_intptr (Ui), Ux,
+                                          to_suitesparse_intptr (p),
+                                          to_suitesparse_intptr (q), Dx,
+                                          to_suitesparse_intptr (do_recip),
+                                          Rs, Numeric);
     }
 
     template <>
@@ -175,8 +182,9 @@
      const double *Ax, void *Symbolic, void **Numeric,
      const double *Control, double *Info)
     {
-      return UMFPACK_DNAME (numeric) (Ap, Ai, Ax, Symbolic, Numeric, Control,
-                                      Info);
+      return UMFPACK_DNAME (numeric) (to_suitesparse_intptr (Ap),
+                                      to_suitesparse_intptr (Ai),
+                                      Ax, Symbolic, Numeric, Control, Info);
     }
 
     template <>
@@ -187,7 +195,10 @@
      const octave_idx_type *Qinit, void **Symbolic,
      const double *Control, double *Info)
     {
-      return UMFPACK_DNAME (qsymbolic) (n_row, n_col, Ap, Ai, Ax, Qinit,
+      return UMFPACK_DNAME (qsymbolic) (n_row, n_col,
+                                        to_suitesparse_intptr (Ap),
+                                        to_suitesparse_intptr (Ai), Ax,
+                                        to_suitesparse_intptr (Qinit),
                                         Symbolic, Control, Info);
     }
 
@@ -212,7 +223,9 @@
      const octave_idx_type *Ai, const double *Ax, octave_idx_type col_form,
      const double *Control)
     {
-      UMFPACK_DNAME (report_matrix) (n_row, n_col, Ap, Ai, Ax,
+      UMFPACK_DNAME (report_matrix) (n_row, n_col,
+                                     to_suitesparse_intptr (Ap),
+                                     to_suitesparse_intptr (Ai), Ax,
                                      col_form, Control);
     }
 
@@ -228,7 +241,7 @@
     umfpack_report_perm<double>
     (octave_idx_type np, const octave_idx_type *Perm, const double *Control)
     {
-      UMFPACK_DNAME (report_perm) (np, Perm, Control);
+      UMFPACK_DNAME (report_perm) (np, to_suitesparse_intptr (Perm), Control);
     }
 
     template <>
@@ -273,10 +286,11 @@
     umfpack_get_lunz<Complex>
     (octave_idx_type *lnz, octave_idx_type *unz, void *Numeric)
     {
-      octave_idx_type ignore1, ignore2, ignore3;
+      suitesparse_integer ignore1, ignore2, ignore3;
 
-      return UMFPACK_ZNAME (get_lunz) (lnz, unz, &ignore1, &ignore2,
-                                       &ignore3, Numeric);
+      return UMFPACK_ZNAME (get_lunz) (to_suitesparse_intptr (lnz),
+                                       to_suitesparse_intptr (unz),
+                                       &ignore1, &ignore2, &ignore3, Numeric);
     }
 
     template <>
@@ -287,13 +301,17 @@
      octave_idx_type *p, octave_idx_type *q, double *Dz,
      octave_idx_type *do_recip, double *Rs, void *Numeric)
     {
-      return UMFPACK_ZNAME (get_numeric) (Lp, Lj,
+      return UMFPACK_ZNAME (get_numeric) (to_suitesparse_intptr (Lp),
+                                          to_suitesparse_intptr (Lj),
                                           reinterpret_cast<double *> (Lz),
-                                          0, Up, Ui,
+                                          0, to_suitesparse_intptr (Up),
+                                          to_suitesparse_intptr (Ui),
                                           reinterpret_cast<double *> (Uz),
-                                          0, p, q,
+                                          0, to_suitesparse_intptr (p),
+                                          to_suitesparse_intptr (q),
                                           reinterpret_cast<double *> (Dz),
-                                          0, do_recip, Rs, Numeric);
+                                          0, to_suitesparse_intptr (do_recip),
+                                          Rs, Numeric);
     }
 
     template <>
@@ -303,7 +321,8 @@
      const Complex *Az, void *Symbolic, void **Numeric,
      const double *Control, double *Info)
     {
-      return UMFPACK_ZNAME (numeric) (Ap, Ai,
+      return UMFPACK_ZNAME (numeric) (to_suitesparse_intptr (Ap),
+                                      to_suitesparse_intptr (Ai),
                                       reinterpret_cast<const double *> (Az),
                                       0, Symbolic, Numeric, Control, Info);
     }
@@ -316,9 +335,12 @@
      const Complex *Az, const octave_idx_type *Qinit,
      void **Symbolic, const double *Control, double *Info)
     {
-      return UMFPACK_ZNAME (qsymbolic) (n_row, n_col, Ap, Ai,
+      return UMFPACK_ZNAME (qsymbolic) (n_row, n_col,
+                                        to_suitesparse_intptr (Ap),
+                                        to_suitesparse_intptr (Ai),
                                         reinterpret_cast<const double *> (Az),
-                                        0, Qinit, Symbolic, Control, Info);
+                                        0, to_suitesparse_intptr (Qinit),
+                                        Symbolic, Control, Info);
     }
 
     template <>
@@ -342,7 +364,9 @@
      const octave_idx_type *Ap, const octave_idx_type *Ai,
      const Complex *Az, octave_idx_type col_form, const double *Control)
     {
-      UMFPACK_ZNAME (report_matrix) (n_row, n_col, Ap, Ai,
+      UMFPACK_ZNAME (report_matrix) (n_row, n_col,
+                                     to_suitesparse_intptr (Ap),
+                                     to_suitesparse_intptr (Ai),
                                      reinterpret_cast<const double *> (Az),
                                      0, col_form, Control);
     }
@@ -359,7 +383,7 @@
     umfpack_report_perm<Complex>
     (octave_idx_type np, const octave_idx_type *Perm, const double *Control)
     {
-      UMFPACK_ZNAME (report_perm) (np, Perm, Control);
+      UMFPACK_ZNAME (report_perm) (np, to_suitesparse_intptr (Perm), Control);
     }
 
     template <>
--- a/liboctave/numeric/sparse-qr.cc	Wed Apr 12 13:38:01 2017 -0400
+++ b/liboctave/numeric/sparse-qr.cc	Wed Apr 12 16:29:50 2017 -0400
@@ -184,8 +184,8 @@
       A.n = ncols;
       // Cast away const on A, with full knowledge that CSparse won't touch it
       // Prevents the methods below making a copy of the data.
-      A.p = const_cast<octave_idx_type *>(a.cidx ());
-      A.i = const_cast<octave_idx_type *>(a.ridx ());
+      A.p = const_cast<suitesparse_integer *>(to_suitesparse_intptr (a.cidx ()));
+      A.i = const_cast<suitesparse_integer *>(to_suitesparse_intptr (a.ridx ()));
       A.x = const_cast<double *>(a.data ());
       A.nz = -1;
 
@@ -950,8 +950,8 @@
       A.n = ncols;
       // Cast away const on A, with full knowledge that CSparse won't touch it
       // Prevents the methods below making a copy of the data.
-      A.p = const_cast<octave_idx_type *>(a.cidx ());
-      A.i = const_cast<octave_idx_type *>(a.ridx ());
+      A.p = const_cast<suitesparse_integer *>(to_suitesparse_intptr (a.cidx ()));
+      A.i = const_cast<suitesparse_integer *>(to_suitesparse_intptr (a.ridx ()));
       A.x = const_cast<cs_complex_t *> (
               reinterpret_cast<const cs_complex_t *> (a.data ()));
       A.nz = -1;
--- a/liboctave/util/module.mk	Wed Apr 12 13:38:01 2017 -0400
+++ b/liboctave/util/module.mk	Wed Apr 12 16:29:50 2017 -0400
@@ -68,6 +68,7 @@
   liboctave/util/oct-mutex.cc \
   liboctave/util/oct-string.cc \
   liboctave/util/oct-shlib.cc \
+  liboctave/util/oct-sparse.cc \
   liboctave/util/pathsearch.cc \
   liboctave/util/lo-regexp.cc \
   liboctave/util/singleton-cleanup.cc \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/util/oct-sparse.cc	Wed Apr 12 16:29:50 2017 -0400
@@ -0,0 +1,80 @@
+/*
+
+Copyright (C) 2017 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+Octave is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if defined (HAVE_CONFIG_H)
+#  include "config.h"
+#endif
+
+#include "lo-error.h"
+#include "oct-sparse.h"
+
+#if (defined (HAVE_AMD) || defined (HAVE_CCOLAMD)               \
+     || defined (HAVE_CHOLMOD) || defined (HAVE_COLAMD)         \
+     || defined (HAVE_CXSPARSE) || defined (HAVE_UMFPACK))
+
+static inline void
+check_suitesparse_integer_size (void)
+{
+  // FIXME: maybe it would be better to make this a configure check and
+  // disable suitesparse if it fails?
+
+  if (sizeof (octave::suitesparse_integer) != sizeof (octave_idx_type))
+    (*current_liboctave_error_handler)
+      ("size of suitesparse integer does not match octave_idx_type!");
+}
+
+namespace octave
+{
+  suitesparse_integer *
+  to_suitesparse_intptr (octave_idx_type *i)
+  {
+    check_suitesparse_integer_size ();
+
+    return reinterpret_cast<suitesparse_integer *> (i);
+  }
+
+  const suitesparse_integer *
+  to_suitesparse_intptr (const octave_idx_type *i)
+  {
+    check_suitesparse_integer_size ();
+
+    return reinterpret_cast<const suitesparse_integer *> (i);
+  }
+
+  octave_idx_type*
+  to_octave_idx_type_ptr (suitesparse_integer *i)
+  {
+    check_suitesparse_integer_size ();
+
+    return reinterpret_cast<octave_idx_type *> (i);
+  }
+
+  const octave_idx_type*
+  to_octave_idx_type_ptr (const suitesparse_integer *i)
+  {
+    check_suitesparse_integer_size ();
+
+    return reinterpret_cast<const octave_idx_type *> (i);
+  }
+}
+
+#endif
--- a/liboctave/util/oct-sparse.h	Wed Apr 12 13:38:01 2017 -0400
+++ b/liboctave/util/oct-sparse.h	Wed Apr 12 16:29:50 2017 -0400
@@ -156,4 +156,30 @@
 #  endif
 #endif
 
+#if (defined (HAVE_AMD) || defined (HAVE_CCOLAMD)               \
+     || defined (HAVE_CHOLMOD) || defined (HAVE_COLAMD)         \
+     || defined (HAVE_CXSPARSE) || defined (HAVE_UMFPACK))
+
+namespace octave
+{
+#  if defined (OCTAVE_ENABLE_64)
+  typedef SuiteSparse_long suitesparse_integer;
+#  else
+  typedef int suitesparse_integer;
+#  endif
+
+  extern suitesparse_integer *
+  to_suitesparse_intptr (octave_idx_type *i);
+
+  extern const suitesparse_integer *
+  to_suitesparse_intptr (const octave_idx_type *i);
+
+  extern octave_idx_type*
+  to_octave_idx_type_ptr (suitesparse_integer *i);
+
+  extern const octave_idx_type*
+  to_octave_idx_type_ptr (const suitesparse_integer *i);
+}
+
 #endif
+#endif