Committed as obvious: character(len=:) is allowed as result in pure
functions - while character(len=*) functions are not. (In the latter
case, the length the function returns depends on the definition of the
caller (!).)
The attached patch was build and regtested on x86-64-linux and committed
as Rev. 187427 to the trunk.
* * *
There are a few other deferred-string patches in the pipeline:
* Function-result related (e.g. REPEAT bugs), see my (RFC) patch, posted
yesterday.
* Alessandro's patch. (The first draft has been posted and reviewed;
Alessandro will soon post an updated version.)
I think the main still missing features are:
"allocate(character(len=var) :: str)" (which is currently rejected) and
deferred-length components of derived types. However, there are still a
couple of other bugs - especially related to arrays/array constructors.
Tobias
2012-05-12 Tobias Burnus <bur...@net-b.de>
PR fortran/49110
PR fortran/52843
* resolve.c (resolve_fl_procedure): Don't regard
character(len=:) as character(*) in the diagnostic.
2012-05-12 Tobias Burnus <bur...@net-b.de>
PR fortran/49110
PR fortran/52843
* gfortran.dg/deferred_type_param_5.f90: New.
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index b3a23ed..9814c14 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -10721,17 +10721,17 @@ resolve_fl_procedure (gfc_symbol *sym, int mp_flag)
/* 5.1.1.5 of the Standard: A function name declared with an asterisk
char-len-param shall not be array-valued, pointer-valued, recursive
or pure. ....snip... A character value of * may only be used in the
following ways: (i) Dummy arg of procedure - dummy associates with
actual length; (ii) To declare a named constant; or (iii) External
function - but length must be declared in calling scoping unit. */
if (sym->attr.function
- && sym->ts.type == BT_CHARACTER
+ && sym->ts.type == BT_CHARACTER && !sym->ts.deferred
&& sym->ts.u.cl && sym->ts.u.cl->length == NULL)
{
if ((sym->as && sym->as->rank) || (sym->attr.pointer)
|| (sym->attr.recursive) || (sym->attr.pure))
{
if (sym->as && sym->as->rank)
gfc_error ("CHARACTER(*) function '%s' at %L cannot be "
"array-valued", sym->name, &sym->declared_at);
--- /dev/null 2012-05-12 08:53:12.703771173 +0200
+++ gcc/gcc/testsuite/gfortran.dg/deferred_type_param_5.f90 2012-05-12 11:27:49.000000000 +0200
@@ -0,0 +1,51 @@
+! { dg-do compile }
+!
+! PR fortran/49110
+! PR fortran/52843
+!
+! Based on a contributed code by jwmwal...@gmail.com
+!
+! Before, character(len=:) result variable were rejected in PURE functions.
+!
+module mod1
+ use iso_c_binding
+ implicit none
+
+contains
+ pure function c_strlen(str)
+ character(KIND = C_CHAR), intent(IN) :: str(*)
+ integer :: c_strlen,i
+
+ i = 1
+ do
+ if (i < 1) then
+ c_strlen = 0
+ return
+ end if
+ if (str(i) == c_null_char) exit
+ i = i + 1
+ end do
+ c_strlen = i - 1
+ end function c_strlen
+ pure function c2fstring(cbuffer) result(string)
+ character(:), allocatable :: string
+ character(KIND = C_CHAR), intent(IN) :: cbuffer(*)
+ integer :: i
+
+ continue
+ string = REPEAT(' ', c_strlen(cbuffer))
+
+ do i = 1, c_strlen(cbuffer)
+ if (cbuffer(i) == C_NULL_CHAR) exit
+ string(i:i) = cbuffer(i)
+ enddo
+
+ string = TRIM(string)
+ end function
+end module mod1
+
+use mod1
+character(len=:), allocatable :: str
+str = c2fstring("ABCDEF"//c_null_char//"GHI")
+if (len(str) /= 6 .or. str /= "ABCDEF") call abort()
+end