https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113503
Bug ID: 113503
Summary: [14 Regression] xtb test miscompilation starting with
r14-870
Product: gcc
Version: 14.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: jakub at gcc dot gnu.org
Target Milestone: ---
Since r14-870-g6c95fe9bc0553743098eeaa739f14b885050fa42 4 xtb tests seem to be
miscompiled, they crash due to memcpy into NULL pointer.
Reduced testcase is:
module xtb_solv_input
implicit none
private
public :: TSolvInput
type :: TSolvInput
character(len=:), allocatable :: solvent
end type
end module
module xtb_main_setup
use xtb_solv_input, only : TSolvInput
private
public :: addSolvationModel
contains
subroutine addSolvationModel(input)
type(TSolvInput), intent(in) :: input
end subroutine
end module
program xtb
use xtb_solv_input, only : TSolvInput
use xtb_main_setup, only : addSolvationModel
integer :: iMol
character(len=*), parameter :: solvents(10) = [character(len=20) ::&
& "h2o", "chcl3", "thf", "acetonitrile", "toluene", &
& "ch2cl2", "ether", "methanol", "cs2", "dmso"]
do iMol = 1, 10
call addSolvationModel(TSolvInput(solvent=trim(solvents(iMol))))
end do
end program
When compiled with -O2 -fno-inline -Wuninitialized starting with that revision
it emits:
xtb.f90:26:70:
26 | call addSolvationModel(TSolvInput(solvent=trim(solvents(iMol))))
| ^
Warning: ‘len.8’ is used uninitialized [-Wuninitialized]
xtb.f90:26:70:
26 | call addSolvationModel(TSolvInput(solvent=trim(solvents(iMol))))
| ^
note: ‘len.8’ declared here
warning. This reduced test doesn't crash, but the unreduced one crashes
exactly because of the uninitialized use - when the uninitialized var happens
to contain some huge value (0x7fffffffffffe0b0 or so in my case), that value is
passed to malloc,
malloc obviously returns NULL as I don't have that much memory and the code
then tries to memcpy "h2o" into NULL.
The bug is visible in the gimple dump already:
integer(kind=8) len.8;
integer(kind=8) slen.9;
try
{
slen.9 = len.8;
slen.18_1 = (sizetype) slen.9;
_2 = MAX_EXPR <slen.18_1, 1>;
_3 = __builtin_malloc (_2);
tsolvinput.6.solvent = _3;
tsolvinput.6._solvent_length = slen.9;
_4 = (integer(kind=8)) imol;
_5 = _4 + -1;
_6 = &solvents[_5];
_gfortran_string_trim (&len.8, &pstr.7, 20, _6);
len.19_7 = len.8;
len.20_8 = (unsigned long) len.19_7;
pstr.21_9 = pstr.7;
_10 = tsolvinput.6.solvent;
__builtin_memcpy (_10, pstr.21_9, len.20_8);
len.22_11 = len.8;
In r14-868 instead it looked like
integer(kind=8) len.8;
integer(kind=8) D.4372;
character(kind=1) * pstr.9;
integer(kind=8) len.10;
try
{
_1 = (integer(kind=8)) imol;
_2 = _1 + -1;
_3 = &solvents[_2];
_gfortran_string_trim (&len.8, &pstr.7, 20, _3);
len.19_4 = len.8;
if (len.19_4 > 0) goto <D.4416>; else goto <D.4417>;
<D.4416>:
pstr.20_5 = pstr.7;
__builtin_free (pstr.20_5);