* [Patch, Fortran] PR 42418: PROCEDURE: Rejects interface which is both specific and generic procedure
@ 2012-07-31 9:59 Janus Weil
2012-07-31 15:33 ` Tobias Burnus
0 siblings, 1 reply; 4+ messages in thread
From: Janus Weil @ 2012-07-31 9:59 UTC (permalink / raw)
To: gfortran, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1918 bytes --]
Hi all,
here is a patch which does several things:
1) It fixes the original problem in the PR (cf. comments 0 and 6) by
adding code which checks if a generic interface has a specific
procedure of the same name (see resolve_procedure_interface).
2) It fixes other problems found along the way (cf. comment 7), which
are all due to the fact that the checks for interface declarations in
PROCEDURE statements came too early (checks for generics, statement
functions and intrinsics are moved from "match_procedure_interface" to
"resolve_procedure_interface"). For the intrinsics we do the same
trick as for PR51081, by setting the flavor at parsing stage and later
setting the INTRINSIC attribute at resolution stage.
3) It does minor cleanup related to "gfc_is_intrinsic", by moving some
checks into the routine, which were typically done before calling the
routine in a several places. (This is also related to the recent patch
for PR51081.) Note that 'use_assoc' is not sufficient to identify a
routine as non-intrinsic (apparently this was wrongly assumed in some
cases).
The patch was regtested successfully on x86_64-unknown-linux-gnu. Ok for trunk?
Cheers,
Janus
2012-07-31 Janus Weil <janus@gcc.gnu.org>
PR fortran/42418
* decl.c (match_procedure_interface): Move some checks to
'resolve_procedure_interface'. Set flavor if appropriate.
* expr.c (gfc_check_pointer_assign): Cleanup of 'gfc_is_intrinsic'.
* intrinsic.c (gfc_is_intrinsic): Additional checks for attributes which
identify a procedure as being non-intrinsic.
* resolve.c (resolve_procedure_interface): Checks moved here from
'match_procedure_interface'. Minor cleanup.
(resolve_formal_arglist,resolve_symbol): Cleanup of
'resolve_procedure_interface'
(resolve_actual_arglist,is_external_proc): Cleanup of
'gfc_is_intrinsic'.
2012-07-31 Janus Weil <janus@gcc.gnu.org>
PR fortran/42418
* gfortran.dg/proc_decl_29.f90: New.
[-- Attachment #2: pr42418_v4.diff --]
[-- Type: application/octet-stream, Size: 8193 bytes --]
Index: gcc/fortran/intrinsic.c
===================================================================
--- gcc/fortran/intrinsic.c (revision 189984)
+++ gcc/fortran/intrinsic.c (working copy)
@@ -902,9 +902,9 @@ gfc_intrinsic_actual_ok (const char *name, const b
}
-/* Given a symbol, find out if it is (and is to be treated) an intrinsic. If
- it's name refers to an intrinsic but this intrinsic is not included in the
- selected standard, this returns FALSE and sets the symbol's external
+/* Given a symbol, find out if it is (and is to be treated as) an intrinsic.
+ If its name refers to an intrinsic, but this intrinsic is not included in
+ the selected standard, this returns FALSE and sets the symbol's external
attribute. */
bool
@@ -913,10 +913,13 @@ gfc_is_intrinsic (gfc_symbol* sym, int subroutine_
gfc_intrinsic_sym* isym;
const char* symstd;
- /* If INTRINSIC/EXTERNAL state is already known, return. */
+ /* If INTRINSIC attribute is already known, return. */
if (sym->attr.intrinsic)
return true;
- if (sym->attr.external)
+
+ /* Check for attributes which prevent the symbol from being INTRINSIC. */
+ if (sym->attr.external || sym->attr.contained
+ || sym->attr.if_source == IFSRC_IFBODY)
return false;
if (subroutine_flag)
Index: gcc/fortran/decl.c
===================================================================
--- gcc/fortran/decl.c (revision 189984)
+++ gcc/fortran/decl.c (working copy)
@@ -4792,41 +4792,20 @@ match_procedure_interface (gfc_symbol **proc_if)
gfc_current_ns = old_ns;
*proc_if = st->n.sym;
- /* Various interface checks. */
if (*proc_if)
{
(*proc_if)->refs++;
/* Resolve interface if possible. That way, attr.procedure is only set
if it is declared by a later procedure-declaration-stmt, which is
- invalid per C1212. */
+ invalid per F08:C1216 (cf. resolve_procedure_interface). */
while ((*proc_if)->ts.interface)
*proc_if = (*proc_if)->ts.interface;
- if ((*proc_if)->generic)
- {
- gfc_error ("Interface '%s' at %C may not be generic",
- (*proc_if)->name);
- return MATCH_ERROR;
- }
- if ((*proc_if)->attr.proc == PROC_ST_FUNCTION)
- {
- gfc_error ("Interface '%s' at %C may not be a statement function",
- (*proc_if)->name);
- return MATCH_ERROR;
- }
- /* Handle intrinsic procedures. */
- if (!((*proc_if)->attr.external || (*proc_if)->attr.use_assoc
- || (*proc_if)->attr.if_source == IFSRC_IFBODY)
- && (gfc_is_intrinsic ((*proc_if), 0, gfc_current_locus)
- || gfc_is_intrinsic ((*proc_if), 1, gfc_current_locus)))
- (*proc_if)->attr.intrinsic = 1;
- if ((*proc_if)->attr.intrinsic
- && !gfc_intrinsic_actual_ok ((*proc_if)->name, 0))
- {
- gfc_error ("Intrinsic procedure '%s' not allowed "
- "in PROCEDURE statement at %C", (*proc_if)->name);
- return MATCH_ERROR;
- }
+ if ((*proc_if)->attr.flavor == FL_UNKNOWN
+ && (*proc_if)->ts.type == BT_UNKNOWN
+ && gfc_add_flavor (&(*proc_if)->attr, FL_PROCEDURE,
+ (*proc_if)->name, NULL) == FAILURE)
+ return MATCH_ERROR;
}
got_ts:
Index: gcc/fortran/expr.c
===================================================================
--- gcc/fortran/expr.c (revision 189985)
+++ gcc/fortran/expr.c (working copy)
@@ -3426,8 +3426,6 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_ex
/* Check for intrinsics. */
gfc_symbol *sym = rvalue->symtree->n.sym;
if (!sym->attr.intrinsic
- && !(sym->attr.contained || sym->attr.use_assoc
- || sym->attr.external || sym->attr.if_source == IFSRC_IFBODY)
&& (gfc_is_intrinsic (sym, 0, sym->declared_at)
|| gfc_is_intrinsic (sym, 1, sym->declared_at)))
{
Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c (revision 189985)
+++ gcc/fortran/resolve.c (working copy)
@@ -146,24 +146,58 @@ static void resolve_symbol (gfc_symbol *sym);
static gfc_try
resolve_procedure_interface (gfc_symbol *sym)
{
- if (sym->ts.interface == sym)
+ gfc_symbol *ifc = sym->ts.interface;
+
+ if (!ifc)
+ return SUCCESS;
+
+ /* Several checks for F08:C1216. */
+ if (ifc == sym)
{
gfc_error ("PROCEDURE '%s' at %L may not be used as its own interface",
sym->name, &sym->declared_at);
return FAILURE;
}
- if (sym->ts.interface->attr.procedure)
+ if (ifc->attr.procedure)
{
gfc_error ("Interface '%s', used by procedure '%s' at %L, is declared "
- "in a later PROCEDURE statement", sym->ts.interface->name,
+ "in a later PROCEDURE statement", ifc->name,
sym->name, &sym->declared_at);
return FAILURE;
}
+ if (ifc->generic)
+ {
+ /* For generic interfaces, check if there is
+ a specific procedure with the same name. */
+ gfc_interface *gen = ifc->generic;
+ while (gen && strcmp (gen->sym->name, ifc->name) != 0)
+ gen = gen->next;
+ if (!gen)
+ {
+ gfc_error ("Interface '%s' at %L may not be generic",
+ ifc->name, &sym->declared_at);
+ return FAILURE;
+ }
+ }
+ if (ifc->attr.proc == PROC_ST_FUNCTION)
+ {
+ gfc_error ("Interface '%s' at %L may not be a statement function",
+ ifc->name, &sym->declared_at);
+ return FAILURE;
+ }
+ if (gfc_is_intrinsic (ifc, 0, ifc->declared_at)
+ || gfc_is_intrinsic (ifc, 1, ifc->declared_at))
+ ifc->attr.intrinsic = 1;
+ if (ifc->attr.intrinsic && !gfc_intrinsic_actual_ok (ifc->name, 0))
+ {
+ gfc_error ("Intrinsic procedure '%s' not allowed in "
+ "PROCEDURE statement at %L", ifc->name, &sym->declared_at);
+ return FAILURE;
+ }
/* Get the attributes from the interface (now resolved). */
- if (sym->ts.interface->attr.if_source || sym->ts.interface->attr.intrinsic)
+ if (ifc->attr.if_source || ifc->attr.intrinsic)
{
- gfc_symbol *ifc = sym->ts.interface;
resolve_symbol (ifc);
if (ifc->attr.intrinsic)
@@ -212,10 +246,10 @@ resolve_procedure_interface (gfc_symbol *sym)
return FAILURE;
}
}
- else if (sym->ts.interface->name[0] != '\0')
+ else if (ifc->name[0] != '\0')
{
gfc_error ("Interface '%s' of procedure '%s' at %L must be explicit",
- sym->ts.interface->name, sym->name, &sym->declared_at);
+ ifc->name, sym->name, &sym->declared_at);
return FAILURE;
}
@@ -273,9 +307,9 @@ resolve_formal_arglist (gfc_symbol *proc)
&proc->declared_at);
continue;
}
- else if (sym->attr.procedure && sym->ts.interface
- && sym->attr.if_source != IFSRC_DECL)
- resolve_procedure_interface (sym);
+ else if (sym->attr.procedure && sym->attr.if_source != IFSRC_DECL
+ && resolve_procedure_interface (sym) == FAILURE)
+ return;
if (sym->attr.if_source != IFSRC_UNKNOWN)
resolve_formal_arglist (sym);
@@ -1672,10 +1706,7 @@ resolve_actual_arglist (gfc_actual_arglist *arg, p
/* If a procedure is not already determined to be something else
check if it is intrinsic. */
- if (!sym->attr.intrinsic
- && !(sym->attr.external || sym->attr.use_assoc
- || sym->attr.if_source == IFSRC_IFBODY)
- && gfc_is_intrinsic (sym, sym->attr.subroutine, e->where))
+ if (gfc_is_intrinsic (sym, sym->attr.subroutine, e->where))
sym->attr.intrinsic = 1;
if (sym->attr.proc == PROC_ST_FUNCTION)
@@ -2601,8 +2632,7 @@ static bool
is_external_proc (gfc_symbol *sym)
{
if (!sym->attr.dummy && !sym->attr.contained
- && !(sym->attr.intrinsic
- || gfc_is_intrinsic (sym, sym->attr.subroutine, sym->declared_at))
+ && !gfc_is_intrinsic (sym, sym->attr.subroutine, sym->declared_at)
&& sym->attr.proc != PROC_ST_FUNCTION
&& !sym->attr.proc_pointer
&& !sym->attr.use_assoc
@@ -12486,8 +12516,7 @@ resolve_symbol (gfc_symbol *sym)
if (sym->attr.external && sym->ts.type != BT_UNKNOWN && !sym->attr.function)
gfc_add_function (&sym->attr, sym->name, &sym->declared_at);
- if (sym->attr.procedure && sym->ts.interface
- && sym->attr.if_source != IFSRC_DECL
+ if (sym->attr.procedure && sym->attr.if_source != IFSRC_DECL
&& resolve_procedure_interface (sym) == FAILURE)
return;
[-- Attachment #3: proc_decl_29.f90 --]
[-- Type: application/octet-stream, Size: 552 bytes --]
! { dg-do compile }
!
! PR 42418: PROCEDURE: Rejects interface which is both specific and generic procedure
!
! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
interface gen
procedure gen
end interface
procedure(gen) :: p1
procedure(gen2) :: p2 ! { dg-error "may not be generic" }
procedure(sf) :: p3 ! { dg-error "may not be a statement function" }
procedure(char) :: p4
interface gen2
procedure char
end interface
sf(x) = x**2
contains
subroutine gen
end subroutine
subroutine char
end subroutine
end
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch, Fortran] PR 42418: PROCEDURE: Rejects interface which is both specific and generic procedure
2012-07-31 9:59 [Patch, Fortran] PR 42418: PROCEDURE: Rejects interface which is both specific and generic procedure Janus Weil
@ 2012-07-31 15:33 ` Tobias Burnus
2012-07-31 18:06 ` Janus Weil
0 siblings, 1 reply; 4+ messages in thread
From: Tobias Burnus @ 2012-07-31 15:33 UTC (permalink / raw)
To: fortran; +Cc: gcc patches
On 07/31/2012 11:50 AM, Janus Weil wrote:
> The patch was regtested successfully on x86_64-unknown-linux-gnu. Ok for trunk?
The patch looks okay. I assume, the patch doesn't help to get PR 54035
fixed,does it? (That PR is about TBP binding to the generic instead of
the specific name.)
Tobias
> 2012-07-31 Janus Weil <janus@gcc.gnu.org>
>
> PR fortran/42418
> * decl.c (match_procedure_interface): Move some checks to
> 'resolve_procedure_interface'. Set flavor if appropriate.
> * expr.c (gfc_check_pointer_assign): Cleanup of 'gfc_is_intrinsic'.
> * intrinsic.c (gfc_is_intrinsic): Additional checks for attributes which
> identify a procedure as being non-intrinsic.
> * resolve.c (resolve_procedure_interface): Checks moved here from
> 'match_procedure_interface'. Minor cleanup.
> (resolve_formal_arglist,resolve_symbol): Cleanup of
> 'resolve_procedure_interface'
> (resolve_actual_arglist,is_external_proc): Cleanup of
> 'gfc_is_intrinsic'.
>
> 2012-07-31 Janus Weil <janus@gcc.gnu.org>
>
> PR fortran/42418
> * gfortran.dg/proc_decl_29.f90: New.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch, Fortran] PR 42418: PROCEDURE: Rejects interface which is both specific and generic procedure
2012-07-31 15:33 ` Tobias Burnus
@ 2012-07-31 18:06 ` Janus Weil
2012-07-31 19:17 ` Janus Weil
0 siblings, 1 reply; 4+ messages in thread
From: Janus Weil @ 2012-07-31 18:06 UTC (permalink / raw)
To: Tobias Burnus; +Cc: fortran, gcc patches
>> The patch was regtested successfully on x86_64-unknown-linux-gnu. Ok for
>> trunk?
>
>
> The patch looks okay.
Thanks!
> I assume, the patch doesn't help to get PR 54035
> fixed,does it? (That PR is about TBP binding to the generic instead of the
> specific name.)
Not directly. Although - since they're not completely unrelated - one
might think about applying a similar strategy for that one. However, I
expect it will be a bit harder to fix. Maybe I'll have a look soon ...
In general I don't really like the sort of special-case treatment that
is needed, e.g. in this PR, to handle generics and specifics with the
same. In the long run, it might be worth to think about a separate
symtree for generics in each namespace. That would also help to
simplify the treatment of 'constructors' etc, but it's surely not a
quick'n'easy project (and I'm not sure if there are any pitfalls
lurking).
Cheers,
Janus
>> 2012-07-31 Janus Weil <janus@gcc.gnu.org>
>>
>> PR fortran/42418
>> * decl.c (match_procedure_interface): Move some checks to
>> 'resolve_procedure_interface'. Set flavor if appropriate.
>> * expr.c (gfc_check_pointer_assign): Cleanup of
>> 'gfc_is_intrinsic'.
>> * intrinsic.c (gfc_is_intrinsic): Additional checks for attributes
>> which
>> identify a procedure as being non-intrinsic.
>> * resolve.c (resolve_procedure_interface): Checks moved here from
>> 'match_procedure_interface'. Minor cleanup.
>> (resolve_formal_arglist,resolve_symbol): Cleanup of
>> 'resolve_procedure_interface'
>> (resolve_actual_arglist,is_external_proc): Cleanup of
>> 'gfc_is_intrinsic'.
>>
>> 2012-07-31 Janus Weil <janus@gcc.gnu.org>
>>
>> PR fortran/42418
>> * gfortran.dg/proc_decl_29.f90: New.
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Patch, Fortran] PR 42418: PROCEDURE: Rejects interface which is both specific and generic procedure
2012-07-31 18:06 ` Janus Weil
@ 2012-07-31 19:17 ` Janus Weil
0 siblings, 0 replies; 4+ messages in thread
From: Janus Weil @ 2012-07-31 19:17 UTC (permalink / raw)
To: Tobias Burnus; +Cc: fortran, gcc patches
>>> The patch was regtested successfully on x86_64-unknown-linux-gnu. Ok for
>>> trunk?
>>
>>
>> The patch looks okay.
>
> Thanks!
Committed as r190017.
Cheers,
Janus
>>> 2012-07-31 Janus Weil <janus@gcc.gnu.org>
>>>
>>> PR fortran/42418
>>> * decl.c (match_procedure_interface): Move some checks to
>>> 'resolve_procedure_interface'. Set flavor if appropriate.
>>> * expr.c (gfc_check_pointer_assign): Cleanup of
>>> 'gfc_is_intrinsic'.
>>> * intrinsic.c (gfc_is_intrinsic): Additional checks for attributes
>>> which
>>> identify a procedure as being non-intrinsic.
>>> * resolve.c (resolve_procedure_interface): Checks moved here from
>>> 'match_procedure_interface'. Minor cleanup.
>>> (resolve_formal_arglist,resolve_symbol): Cleanup of
>>> 'resolve_procedure_interface'
>>> (resolve_actual_arglist,is_external_proc): Cleanup of
>>> 'gfc_is_intrinsic'.
>>>
>>> 2012-07-31 Janus Weil <janus@gcc.gnu.org>
>>>
>>> PR fortran/42418
>>> * gfortran.dg/proc_decl_29.f90: New.
>>
>>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-07-31 18:36 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-31 9:59 [Patch, Fortran] PR 42418: PROCEDURE: Rejects interface which is both specific and generic procedure Janus Weil
2012-07-31 15:33 ` Tobias Burnus
2012-07-31 18:06 ` Janus Weil
2012-07-31 19:17 ` Janus Weil
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).