All,

Attached is a patch which extends the DEC STRUCTURE support to include
special fields named '%FILL'. These fields generate anonymous
inaccessible components, commonly used in DEC FORTRAN to control
alignment of fields within STRUCTUREs. The patch is fairly
straightforward. The match is performed during parsing in decl.c
(variable_decl) by generating a component with an internal anonymous
name which is an invalid Fortran identifier to replace any components
specified as '%FILL'.

Regtests on x86_64-redhat-linux. OK for trunk?

---
Fritz Reese


>From a94d1aefe608447ff0de469ca90cbcc4942f6168 Mon Sep 17 00:00:00 2001
From: Fritz Reese <reese-fr...@zai.com>
Date: Mon, 31 Jul 2017 14:18:25 -0400
Subject: [PATCH] Support for legacy %FILL field in STRUCTUREs.

    gcc/fortran/
        * decl.c (attr_seen): New static variable.
        * decl.c (variable_decl): Match %FILL in STRUCTURE body.
        * gfortran.texi: Update documentation.

    gcc/testsuite/gfortran.dg/
        * dec_structure_18.f90, dec_structure_19.f90, dec_structure_20.f90,
        dec_structure_21.f90: New.
---
From a94d1aefe608447ff0de469ca90cbcc4942f6168 Mon Sep 17 00:00:00 2001
From: Fritz Reese <reese-fr...@zai.com>
Date: Mon, 31 Jul 2017 14:18:25 -0400
Subject: [PATCH] Support for legacy %FILL field in STRUCTUREs.

    gcc/fortran/
	* decl.c (attr_seen): New static variable.
	* decl.c (variable_decl): Match %FILL in STRUCTURE body.
	* gfortran.texi: Update documentation.

    gcc/testsuite/gfortran.dg/
	* dec_structure_18.f90, dec_structure_19.f90, dec_structure_20.f90,
	dec_structure_21.f90: New.
---
 gcc/fortran/decl.c                             | 56 +++++++++++++++++++++++++-
 gcc/fortran/gfortran.texi                      | 14 +++++++
 gcc/testsuite/gfortran.dg/dec_structure_18.f90 | 38 +++++++++++++++++
 gcc/testsuite/gfortran.dg/dec_structure_19.f90 | 38 +++++++++++++++++
 gcc/testsuite/gfortran.dg/dec_structure_20.f90 | 18 +++++++++
 gcc/testsuite/gfortran.dg/dec_structure_21.f90 | 10 +++++
 6 files changed, 172 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_18.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_19.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_20.f90
 create mode 100644 gcc/testsuite/gfortran.dg/dec_structure_21.f90

diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index bd310703557..0c56b4010bc 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -54,6 +54,7 @@ static gfc_typespec current_ts;
 static symbol_attribute current_attr;
 static gfc_array_spec *current_as;
 static int colon_seen;
+static int attr_seen;
 
 /* The current binding label (if any).  */
 static const char* curr_binding_label;
@@ -2140,6 +2141,7 @@ static match
 variable_decl (int elem)
 {
   char name[GFC_MAX_SYMBOL_LEN + 1];
+  static unsigned int fill_id = 0;
   gfc_expr *initializer, *char_len;
   gfc_array_spec *as;
   gfc_array_spec *cp_as; /* Extra copy for Cray Pointees.  */
@@ -2157,9 +2159,47 @@ variable_decl (int elem)
   /* When we get here, we've just matched a list of attributes and
      maybe a type and a double colon.  The next thing we expect to see
      is the name of the symbol.  */
-  m = gfc_match_name (name);
+
+  /* If we are parsing a structure with legacy support, we allow the symbol
+     name to be '%FILL' which gives it an anonymous (inaccessible) name.  */
+  m = MATCH_NO;
+  gfc_gobble_whitespace ();
+  if (gfc_peek_ascii_char () == '%')
+    {
+      gfc_next_ascii_char ();
+      m = gfc_match ("fill");
+    }
+
   if (m != MATCH_YES)
-    goto cleanup;
+    {
+      m = gfc_match_name (name);
+      if (m != MATCH_YES)
+	goto cleanup;
+    }
+
+  else
+    {
+      m = MATCH_ERROR;
+      if (gfc_current_state () != COMP_STRUCTURE)
+	{
+	  if (flag_dec_structure)
+	    gfc_error ("%s not allowed outside STRUCTURE at %C", "%FILL");
+	  else
+	    gfc_error ("%s at %C is a DEC extension, enable with "
+		       "%<-fdec-structure%>", "%FILL");
+	  goto cleanup;
+	}
+
+      if (attr_seen)
+	{
+	  gfc_error ("%s entity cannot have attributes at %C", "%FILL");
+	  goto cleanup;
+	}
+
+      /* %FILL components are given invalid fortran names.  */
+      snprintf (name, GFC_MAX_SYMBOL_LEN + 1, "%%FILL%u", fill_id++);
+      m = MATCH_YES;
+    }
 
   var_locus = gfc_current_locus;
 
@@ -2260,6 +2300,14 @@ variable_decl (int elem)
 	}
     }
 
+  /* %FILL components may not have initializers.  */
+  if (strncmp (name, "%FILL", 5) == 0 && gfc_match_eos () != MATCH_YES)
+    {
+      gfc_error ("%s entity cannot have an initializer at %C", "%FILL");
+      m = MATCH_ERROR;
+      goto cleanup;
+    }
+
   /*  If this symbol has already shown up in a Cray Pointer declaration,
       and this is not a component declaration,
       then we want to set the type & bail out.  */
@@ -3858,6 +3906,7 @@ match_attr_spec (void)
 
   current_as = NULL;
   colon_seen = 0;
+  attr_seen = 0;
 
   /* See if we get all of the keywords up to the final double colon.  */
   for (d = GFC_DECL_BEGIN; d != GFC_DECL_END; d++)
@@ -4226,6 +4275,8 @@ match_attr_spec (void)
     {
       if (seen[d] == 0)
 	continue;
+      else
+        attr_seen = 1;
 
       if ((d == DECL_STATIC || d == DECL_AUTOMATIC)
 	  && !flag_dec_static)
@@ -4434,6 +4485,7 @@ cleanup:
   gfc_current_locus = start;
   gfc_free_array_spec (current_as);
   current_as = NULL;
+  attr_seen = 0;
   return m;
 }
 
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 85afdda46ef..145ec7fb9ab 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -2220,6 +2220,20 @@ rules and exceptions:
 @item Structures act like derived types with the @code{SEQUENCE} attribute.
 Otherwise they may contain no specifiers.
 
+@item Structures may contain a special field with the name @code{%FILL}.
+This will create an anonymous component which cannot be accessed but occupies
+space just as if a component of the same type was declared in its place, useful
+for alignment purposes.  As an example, the following structure will consist
+of at least sixteen bytes:
+
+@smallexample
+structure /padded/
+  character(4) start
+  character(8) %FILL
+  character(4) end
+end structure
+@end smallexample
+
 @item Structures may share names with other symbols. For example, the following
 is invalid for derived types, but valid for structures:
 
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_18.f90 b/gcc/testsuite/gfortran.dg/dec_structure_18.f90
new file mode 100644
index 00000000000..1e6b229216b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_18.f90
@@ -0,0 +1,38 @@
+      ! { dg-do run }
+      ! { dg-options "-fdec-structure -ffixed-form" }
+      !
+      ! Test the %FILL component extension.
+      !
+      implicit none
+
+      structure /s/
+        character(2) i
+        character(2) %fill
+        character(2) j
+      end structure
+
+      structure /s2/
+        character buf(6)
+      end structure
+
+      record /s/ x
+      record /s2/ y
+      equivalence (x, y)
+
+      x.i = '12'
+      x.j = '34'
+
+      if (y.buf(1) .ne. '1') then
+        call abort
+      endif
+      if (y.buf(2) .ne. '2') then
+        call abort
+      endif
+      if (y.buf(5) .ne. '3') then
+        call abort
+      endif
+      if (y.buf(6) .ne. '4') then
+        call abort
+      endif
+
+      end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_19.f90 b/gcc/testsuite/gfortran.dg/dec_structure_19.f90
new file mode 100644
index 00000000000..9ea0b3efe13
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_19.f90
@@ -0,0 +1,38 @@
+! { dg-do compile }
+! { dg-options "-fdec-structure -ffree-form" }
+!
+! Test the %FILL component extension.
+!
+implicit none
+
+structure /s/
+  character(2) i
+  character(2) %fill
+  character(2) j
+end structure
+
+structure /s2/
+  character buf(6)
+end structure
+
+record /s/ x
+record /s2/ y
+equivalence (x, y)
+
+x.i = "12"
+x.j = "34"
+
+if (y.buf(1) .ne. '1') then
+  call abort
+endif
+if (y.buf(2) .ne. '2') then
+  call abort
+endif
+if (y.buf(5) .ne. '3') then
+  call abort
+endif
+if (y.buf(6) .ne. '4') then
+  call abort
+endif
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_20.f90 b/gcc/testsuite/gfortran.dg/dec_structure_20.f90
new file mode 100644
index 00000000000..9e952040076
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_20.f90
@@ -0,0 +1,18 @@
+      ! { dg-do compile }
+      ! { dg-options "-fdec-structure" }
+      !
+      ! Test error handling for %FILL
+      !
+      implicit none
+
+      structure /s/
+        integer(2) i /3/
+        integer(2) %fill /4/ ! { dg-error "cannot have an initializer" }
+        integer(2), pointer :: %fill ! { dg-error "cannot have attributes" }
+      end structure
+
+      type t
+        integer %fill ! { dg-error "not allowed outside STRUCTURE" }
+      endtype
+
+      end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_21.f90 b/gcc/testsuite/gfortran.dg/dec_structure_21.f90
new file mode 100644
index 00000000000..64e8ca39e46
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_21.f90
@@ -0,0 +1,10 @@
+      ! { dg-do compile }
+      ! { dg-options "-ffixed-form" }
+      !
+      ! Test errors for %FILL without -fdec-structure.
+      !
+      implicit none
+
+      character(2) %fill ! { dg-error "is a DEC extension" }
+
+      end
-- 
2.12.2

Reply via email to