Skip to content

jxbforce reads uninitialized bsubs(ns,:) in the js = ns pass #8

Description

@CharlesCNorton

bsubs in jxbforce is a local array (jxbforce.f90:46). The radial loop (jxbforce.f90:168) fills it for js = 2..ns-1 only:

! jxbforce.f90:116
  bsubs(1,:) = 0
! jxbforce.f90:171-173
     IF (js.gt.1 .and. js.lt.ns) THEN
        bsubs(js,:) = cp5*(bsubsh(js,:) + bsubsh(js+1,:))
     END IF

The pass at js = ns reads row ns anyway, at jxbforce.f90:184 (bs1=>bsubs(js,:), into fsym_fft for lasym) and jxbforce.f90:192 (bsubs_s(:) = bsubs(js,:)), and Fourier-transforms it at 233. The edge value is only assigned after the loop (jxbforce.f90:522).

Built with

-fcheck=all -finit-real=snan -ffpe-trap=invalid,zero,overflow

every case aborts there: input.cth_like_fixed_bdy at jxbforce.f90:233, the same input with LASYM = T at fsym_fft.f90:52. Rows ns of bsubsu, bsubsv, bsubuv and bsubvu are never consumed (the current loop is js = 2, ns1, jxbforce.f90:594), so the wout and jxbout are unchanged to roundoff when bsubs = 0 is added at entry; with that one line the instrumented build runs every case of the VMEC++ test set without a trap.

The 2017 VMEC2000 8.52 source has the same local array and the same loop, and there the post-loop rule bsubs(ns,:) = 2*bsubs(ns,:) - bsubs(ns-1,:) consumed the uninitialized row as well. The rule at jxbforce.f90:522 avoids that; the pass inside the loop still reads it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions