This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, Fortran] ABSTRACT INTERFACE


Hi Tobias,

To start with the most important:

Is the attached patch ok for the trunk? Regression tested on
x86_64-unknown-linux-gnu.


Tobias Schlüter wrote:
>> +    case INTERFACE_ABSTRACT:
>>        gfc_error ("Missing generic specification in USE statement at
>> %C");
> Please add a test for this error.  In general all error messages
> should be tested.
I think this is impossible. gfc_match_interface has difficulties
returning INTERFACE_NAMELESS as gfc_match_name() [essentially] either
gives an error or matches an (existing or nonexisting) name. But
INTERFACE_ABSTRACT is *never* returned. However, it is needed in
module.c since if not all enum possibilities have a "case..:" in the
switch() block, the compiler bails out with an error.

As compensation I add a test case for -std=f95 ;-)

>> +      match ("abstract interface", gfc_match_abstract_interface,
>> ST_INTERFACE);
> This should probably be "abstract% interface" (i.e. with an obligatory
> blank).
I think I'm not alone forgetting that Fortran ignores at many places
spaces; while they are here required ...

>> +    gfc_error ("Name of ABSTRACT INTERFACE at %C cannot be the same
>> as "
>> +           "an intrinsic type: %s",gfc_new_block->name);
> You're missing some intrinsic types there.
... they are optional for "double precision" and "double complex".

Thanks for reminding and spotting these!


> I take it that there is no way of using this feature by itself?
Not really. ABSTRACT INTERFACEs only make sense as "name" in
PROCEDURE([name]).


PROCEDURE (without pointers) acts as extended version of the EXTERNAL
statement:

- PROCEDURE() or PROCEDURE(REAL) etc. do the same as EXTERNAL (except
that bind(C) is allowed)

- PROCEDURE(abstract interface name)  saves the typing of several
interfaces for functions which have the same interface

- PROCEDURE(existing procedure) does the same if one has already an
interface or use/host associated function with the needed interface


(The real fun of PROCEDURE starts with (procedure) POINTER, e.g.
type  t
  procedure(), pointer, pass(x_this) :: p => null
  type(t), pointer :: next => null
end type t
where call mytype%p() calls the procedure with "mytype" as argument to
"x_this=".)


Tobias
2007-08-18  Tobias Burnus  <burnus@net-b.de>

	* gfortran.h: Add declaration for gfc_is_intrinsic_typename.
	* symbol.c: Add function gfc_is_intrinsic_typename.
	* parse.c (decode_statement): Check for space in ABSTRACT INTERFACE.
	(parse_interface): Use gfc_is_intrinsic_typename.
	* decl.c (gfc_match_derived_decl): Ditto.

2007-08-18  Tobias Burnus  <burnus@net-b.de>

	* gfortran.dg/interface_abstract_2.f90: New.
	* gfortran.dg/interface_abstract_1.f90: Fix typo.

Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h	(revision 127612)
+++ gcc/fortran/gfortran.h	(working copy)
@@ -2056,6 +2059,7 @@ try gfc_add_new_implicit_range (int, int
 try gfc_merge_new_implicit (gfc_typespec *);
 void gfc_set_implicit_none (void);
 void gfc_check_function_type (gfc_namespace *);
+bool gfc_is_intrinsic_typename (const char *, const char *);
 
 gfc_typespec *gfc_get_default_type (gfc_symbol *, gfc_namespace *);
 try gfc_set_default_type (gfc_symbol *, int, gfc_namespace *);
Index: gcc/fortran/symbol.c
===================================================================
--- gcc/fortran/symbol.c	(revision 127612)
+++ gcc/fortran/symbol.c	(working copy)
@@ -2909,6 +2910,29 @@ gfc_traverse_ns (gfc_namespace *ns, void
 }
 
 
+/* Tests whether name is the name of an intrinsic type. If it is
+   the passed error_message is printed and TRUE is returned.
+   The error message must to contain a single %s for the name.  */
+
+bool
+gfc_is_intrinsic_typename (const char *name, const char *error_message)
+{
+  if (strcmp (name, "integer") == 0
+      || strcmp (name, "real") == 0
+      || strcmp (name, "character") == 0
+      || strcmp (name, "logical") == 0
+      || strcmp (name, "complex") == 0
+      || strcmp (name, "doubleprecision") == 0
+      || strcmp (name, "doublecomplex") == 0)
+    {
+      gfc_error (error_message, name);
+      return true;
+    }
+
+  return false;
+}
+
+
 /* Return TRUE if the symbol is an automatic variable.  */
 
 static bool
Index: gcc/fortran/parse.c
===================================================================
--- gcc/fortran/parse.c	(revision 127612)
+++ gcc/fortran/parse.c	(working copy)
@@ -172,7 +172,8 @@ decode_statement (void)
   switch (c)
     {
     case 'a':
-      match ("abstract interface", gfc_match_abstract_interface, ST_INTERFACE);
+      match ("abstract% interface", gfc_match_abstract_interface,
+	     ST_INTERFACE);
       match ("allocate", gfc_match_allocate, ST_ALLOCATE);
       match ("allocatable", gfc_match_allocatable, ST_ATTR_DECL);
       match ("assign", gfc_match_assign, ST_LABEL_ASSIGNMENT);
@@ -1799,13 +1805,11 @@ loop:
   if (current_interface.type == INTERFACE_ABSTRACT)
     {
       gfc_new_block->attr.abstract = 1;
-      if (!strcmp(gfc_new_block->name,"integer")
-	  || !strcmp(gfc_new_block->name,"real")
-	  || !strcmp(gfc_new_block->name,"complex")
-	  || !strcmp(gfc_new_block->name,"character")
-	  || !strcmp(gfc_new_block->name,"logical"))
-	gfc_error ("Name of ABSTRACT INTERFACE at %C cannot be the same as "
-		   "an intrinsic type: %s",gfc_new_block->name);
+
+      /* Print an error if it has the name of an intrinsic type.  */
+      gfc_is_intrinsic_typename (gfc_new_block->name,
+				 "Name '%s' of ABSTRACT INTERFACE at %C "
+				 "cannot be the same as an intrinsic type");
     }
 
   push_state (&s2, new_state, gfc_new_block);
Index: gcc/fortran/decl.c
===================================================================
--- gcc/fortran/decl.c	(revision 127612)
+++ gcc/fortran/decl.c	(working copy)
@@ -5472,18 +5618,9 @@ gfc_match_derived_decl (void)
      'double {precision,complex}' types don't get past the name
      matcher, unless they're written as a single word or in fixed
      form.  */
-  if (strcmp (name, "integer") == 0
-      || strcmp (name, "real") == 0
-      || strcmp (name, "character") == 0
-      || strcmp (name, "logical") == 0
-      || strcmp (name, "complex") == 0
-      || strcmp (name, "doubleprecision") == 0
-      || strcmp (name, "doublecomplex") == 0)
-    {
-      gfc_error ("Type name '%s' at %C cannot be the same as an intrinsic "
-		 "type", name);
-      return MATCH_ERROR;
-    }
+  if (gfc_is_intrinsic_typename (name, "Type name '%s' at %C cannot be the "
+				       "same as an intrinsic type"))
+    return MATCH_ERROR;
 
   if (gfc_get_symbol (name, NULL, &sym))
     return MATCH_ERROR;
Index: gcc/testsuite/gfortran.dg/interface_abstract_2.f90
===================================================================
--- gcc/testsuite/gfortran.dg/interface_abstract_2.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/interface_abstract_2.f90	(revision 0)
@@ -0,0 +1,7 @@
+! { dg-do compile }
+! { dg-options "-std=f95" }
+abstract interface ! { dg-error "Fortran 2003: ABSTRACT INTERFACE" }
+  subroutine two()
+  end subroutine two
+end interface ! { dg-error "Expecting END PROGRAM statement" }
+end
Index: gcc/testsuite/gfortran.dg/interface_abstract_1.f90
===================================================================
--- gcc/testsuite/gfortran.dg/interface_abstract_1.f90	(revision 127614)
+++ gcc/testsuite/gfortran.dg/interface_abstract_1.f90	(working copy)
@@ -9,7 +9,7 @@ abstract interface
   end subroutine two
   subroutine three() bind(C,name="three") ! { dg-error "NAME not allowed on BIND.C. for ABSTRACT INTERFACE" }
   end subroutine three ! { dg-error "Expecting END INTERFACE statement" }
-  subroutine real() ! { dg-error "cannot be be the same as an intrinsic type" }
+  subroutine real() ! { dg-error "cannot be the same as an intrinsic type" }
   end subroutine real
 end interface
 end

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]