This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/83344] Use of uninitialized memory with ASSOCIATE and strings
- From: "kargl at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 12 Dec 2017 18:34:49 +0000
- Subject: [Bug fortran/83344] Use of uninitialized memory with ASSOCIATE and strings
- Auto-submitted: auto-generated
- References: <bug-83344-4@http.gcc.gnu.org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83344
kargl at gcc dot gnu.org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |kargl at gcc dot gnu.org
--- Comment #3 from kargl at gcc dot gnu.org ---
(In reply to Janne Blomqvist from comment #2)
> Seems it's wrong at least to access value.character.length if the expression
> isn't a constant? So,
>
> diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
> index d1a2368..017b9f7 100644
> --- a/gcc/fortran/resolve.c
> +++ b/gcc/fortran/resolve.c
> @@ -8628,9 +8628,17 @@ resolve_assoc_var (gfc_symbol* sym, bool
> resolve_target)
> sym->ts.u.cl = target->ts.u.cl;
>
> if (!sym->ts.u.cl->length && !sym->ts.deferred)
> - sym->ts.u.cl->length
> - = gfc_get_int_expr (gfc_charlen_int_kind,
> - NULL, target->value.character.length);
> + {
> + if (target->expr_type == EXPR_CONSTANT)
> + sym->ts.u.cl->length
> + = gfc_get_int_expr (gfc_charlen_int_kind,
> + NULL, target->value.character.length);
> + else
> + {
> + // What now?
> + // sym->ts.deferred = true; // Hack that doesn't quite work..
> + }
> + }
> }
Well, I went down the rabbit hole, and I have concluded that gfortran
simply handles a selector with CHARACTER type wrong. The standard
states
The associating entity assumes the declared type and
type parameters of the selector.
In the testcase of comment #1, this is CHARACTER(LEN=1).
Here's an even uglier testcase,
program foo
implicit none
character(len=1) a
character(len=2) b
character(len=3) c
a = 'a'; call bar(a)
b = 'bb'; call bar(b)
c = 'ccc'; call bar(c)
a = 'a'; call bah(a)
b = 'bb'; call bah(b)
c = 'ccc'; call bah(c)
contains
subroutine bar(x)
implicit none
character(len=*), intent(in) :: x
write(*,'(A,I0,A)') 'len('//trim(x)//') = ', len(x)
end subroutine bar
subroutine bah(x)
implicit none
character(len=*), intent(in) :: x
write(*,'(A,I0,A)') 'len('//trim(x)//') = ', len(x)
associate(y => x)
write(*,'(A,I0,A)') 'len('//trim(y)//') = ', len(y)
end associate
end subroutine bah
end program foo
gfortran 6, 7, and trunk all give
% gfc6 -o z a.f90 && ./z
len(a) = 1
len(bb) = 2
len(ccc) = 3
len() = 0
len() = 0
len() = 0
len() = 0
len() = 0
len() = 0
In trans-stmt.c, gfc_trans_associate_var seems to be somewhat
complicated by the need to handle polymorphic entities, o I
get lost very quickly.