Fix integer overflow in DBDSQR

As noted in lapack issue 135, an integer overflow in the calculation of the iteration limit could lead to an immediate return without any iterations having been performed if the input matrix is sufficiently big.
This commit is contained in:
Martin Kroeker 2017-03-24 15:34:28 +01:00 committed by GitHub
parent 9254a701f3
commit c6f25eeb8f
1 changed files with 22 additions and 6 deletions

View File

@ -214,6 +214,16 @@
*> through the inner loop exceeds MAXITR*N**2. *> through the inner loop exceeds MAXITR*N**2.
*> \endverbatim *> \endverbatim
* *
*> \par Note:
* ===========
*>
*> \verbatim
*> Bug report from Cezary Dendek.
*> On March 23rd 2017, the INTEGER variable MAXIT = MAXITR*N**2 is
*> removed since it can overflow pretty easily (for N larger or equal
*> than 18,919). We instead use MAXITDIVN = MAXITR*N.
*> \endverbatim
*
* Authors: * Authors:
* ======== * ========
* *
@ -266,8 +276,8 @@
* .. * ..
* .. Local Scalars .. * .. Local Scalars ..
LOGICAL LOWER, ROTATE LOGICAL LOWER, ROTATE
INTEGER I, IDIR, ISUB, ITER, J, LL, LLL, M, MAXIT, NM1, INTEGER I, IDIR, ISUB, ITER, ITERDIVN, J, LL, LLL, M,
$ NM12, NM13, OLDLL, OLDM $ MAXITDIVN, NM1, NM12, NM13, OLDLL, OLDM
DOUBLE PRECISION ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU, DOUBLE PRECISION ABSE, ABSS, COSL, COSR, CS, EPS, F, G, H, MU,
$ OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL, $ OLDCS, OLDSN, R, SHIFT, SIGMN, SIGMX, SINL,
$ SINR, SLL, SMAX, SMIN, SMINL, SMINOA, $ SINR, SLL, SMAX, SMIN, SMINL, SMINOA,
@ -300,7 +310,7 @@
ELSE IF( NRU.LT.0 ) THEN ELSE IF( NRU.LT.0 ) THEN
INFO = -4 INFO = -4
ELSE IF( NCC.LT.0 ) THEN ELSE IF( NCC.LT.0 ) THEN
INFO = -5 INFO = -5NM1,
ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR. ELSE IF( ( NCVT.EQ.0 .AND. LDVT.LT.1 ) .OR.
$ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN $ ( NCVT.GT.0 .AND. LDVT.LT.MAX( 1, N ) ) ) THEN
INFO = -9 INFO = -9
@ -412,8 +422,9 @@
* (MAXIT is the maximum number of passes through the inner * (MAXIT is the maximum number of passes through the inner
* loop permitted before nonconvergence signalled.) * loop permitted before nonconvergence signalled.)
* *
MAXIT = MAXITR*N*N MAXITDIVN = MAXITR*N
ITER = 0 ITERDIVN = 0
ITER = -1
OLDLL = -1 OLDLL = -1
OLDM = -1 OLDM = -1
* *
@ -429,8 +440,13 @@
* *
IF( M.LE.1 ) IF( M.LE.1 )
$ GO TO 160 $ GO TO 160
IF( ITER.GT.MAXIT ) *
IF( ITER.GE.N ) THEN
ITER = ITER - N
ITERDIVN = ITERDIVN + 1
IF (ITERDIVN.GE.MAXITDIVN )
$ GO TO 200 $ GO TO 200
ENDIF
* *
* Find diagonal block of matrix to work on * Find diagonal block of matrix to work on
* *