Correct bug reported by Alex Zotkevich from Intel
authorlangou <langou@users.noreply.github.com>
Tue, 26 Nov 2013 19:36:29 +0000 (19:36 +0000)
committerlangou <langou@users.noreply.github.com>
Tue, 26 Nov 2013 19:36:29 +0000 (19:36 +0000)
commiteafd3b894608e31f960aea41620d2c761837a932
treeb32b9c9fdf45bb37c661413079f06901f0c2994f
parentf27b681ff5c8eacee4041eadead1ef3fbfd3df2e
Correct bug reported by Alex Zotkevich from Intel
See: http://icl.utk.edu/lapack-forum/viewtopic.php?f=13&t=4392

Bug: During workspace computation, LAPACK code CGESVD was calling other
subroutines (e.g. CGEQRF) with REAL DUM variable as COMPLEX WORK variable.  DUM
(in CGESVD) is REAL while WORK (in called subroutines) is COMPLEX.  This
corrupts the stack when a value is set in WORK.

Fix: In CGESVD, use the COMPLEX CDUM variable (already present in the code)
instead of the REAL DUM variable.  Since I was at it, the COMPLEX "TAU"
variables (not referenced anyway) were passed the REAL DUM variable, I changed
the code so that the COMPLEX CDUM variable is passed. This is cleaner like
this.

Same problem with ZGESVD. Same fix.

Alex's post:
Hi, We recently found a stack corruption issue in (C,Z)GESVD that potentially
could even lead to incorrect xerbla error message.  In ZGESVD array DUM which
is used in LWORK query is a double precision array of size 1 allocated on
stack:
DOUBLE PRECISION DUM( 1 )
DUM comes to ( ZGEQRF, ZUNGQR, ... ) as a WORK array to return an optimal LWORK
value.  But in ( ZGEQRF, ZUNGQR, ... ) array WORK is declared as a COMPLEX*16
array. So WORK(1) = 1 corrupts the stack as it deals with complex value while
pointer on input of the function is a pointer to double: (oooooooo|xxxxxxxx),
oooooooo fills with LWORK value, xxxxxxxx corrupts. Let compiler use xxxxxxxx
to hold some value. After LWORK query the value will turn to be a zero.  "Hacky
fix" would be to allocate DUM array of size 2.
W.B.R.
Alex Zotkevich
SRC/cgesvd.f
SRC/zgesvd.f