Bug 29786 - [4.1/4.2/4.3 Regression] Initialization of overlapping variables: Not implemented
Summary: [4.1/4.2/4.3 Regression] Initialization of overlapping variables: Not impleme...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P5 normal
Target Milestone: 4.1.3
Assignee: Paul Thomas
URL:
Keywords: rejects-valid
: 31672 (view as bug list)
Depends on:
Blocks: 19292
  Show dependency treegraph
 
Reported: 2006-11-09 19:50 UTC by Bernhard Reutner-Fischer
Modified: 2007-06-11 22:41 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-01-12 06:00:50


Attachments
The patch promised above (4.72 KB, patch)
2007-01-12 08:12 UTC, Paul Thomas
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Bernhard Reutner-Fischer 2006-11-09 19:50:13 UTC
$ cat equiv.hm.f 
      INTEGER         i
      PARAMETER           (i = 55)
      INTEGER         o
      INTEGER         NUNITS(i)
      equivalence (o,nunits(16))
      data o/16/
      data nunits(18)/18/
      end
$ gfortran-4.3-HEAD -c -o /dev/null equiv.hm.f
equiv.hm.f:5:

      equivalence (o,nunits(16))                                        
                          1
Error: Initialized objects 'o' and 'nunits'  cannot both be in the EQUIVALENCE statement at (1)

Works fine with g77-3.4.6
Comment 1 Paul Thomas 2006-11-09 20:14:18 UTC
Confirmed

Paul
Comment 2 Paul Thomas 2006-11-10 08:25:53 UTC
(In reply to comment #1)
14.6.3.3 Association of scalar data objects
...snip...
A storage unit shall not be explicitly initialized more than once in a program. Explicit initialization overrides default initialization, and default initialization for an object of derived type overrides default initialization for a component of the object (4.4.1). Default initialization may be specified
for a storage unit that is storage associated provided the objects or subobjects supplying the default initialization are of the same type and type parameters, and supply the same value for the storage unit.

This is intended to be general, I think; ie. to apply to more than scalar data objects.  In any case, prior usage requires that "storage unit" be understood in its complete generality.

The problem occurs in resolve.c:6674, where there is no attempt to see if the storage unit is the same for scalar/array-ref or array-ref/array-ref equivalences and data statements.  This is OK for F90 initialization, where arrays are completely initialized, but not for data statements.

If the error is suppressed by excluding (sym->attr.data && sym->as != NULL), we run into a todo in trans-common.c:

pr29786.f90: In function 'MAIN__':
pr29786.f90:1: fatal error: gfc_todo: Not Implemented: Initialization of overlap
ping variables compilation terminated.

This looks like one of Sherlock Holme's "three pipers".

Paul

Index: gcc/fortran/resolve.c
===================================================================
*** gcc/fortran/resolve.c       (révision 118551)
--- gcc/fortran/resolve.c       (copie de travail)
*************** resolve_equivalence (gfc_equiv *eq)
*** 6671,6677 ****

        /* An equivalence statement cannot have more than one initialized
         object.  */
!       if (sym->value)
        {
          if (value_name != NULL)
            {
--- 6671,6677 ----

        /* An equivalence statement cannot have more than one initialized
         object.  */
!       if (sym->value && !(sym->attr.data && sym->as != NULL))
        {
          if (value_name != NULL)
            {
Comment 3 Paul Thomas 2007-01-12 06:00:50 UTC
The attached bootstraps and regtests on IA64/FC5 - it even fixes the bug, as the testcase shows. (I will have to do the attaching a bit later - whatever I try with cookies does not seem to work right now.)

The patch works by checking for overlapping equivalence members with initializers, which gfc already did; on detecting such overlaps, a new char* field is created that spans the entire union. The equivalence group is then scanned for initializers, which are then byte-wize converted to char* (Note that this is half the job of simplify_array_transfer:) ).  The char* in it's turn is converted into a tree-ssa vector constructor, which becomes the only initializer for the union.

Another approach to this would have been to create a structure field, with components corresponding to the non-null, non-overlapping constructors.  I did not do this on grounds of simplicity.

The patch does not implement overlapping derived types with initializers; it could be done without too much trouble and probably should be, in spite of all the gotcha's that are involved in putting derived types in equivalences.

The part of the patch that is giving me pause is the conversion of integers; because gmp does not offer a mpz_t to signed long long, I used the conversion in tree-const.c and write from two longs.  These have to be ordered according to endian-ness.  Could somebody advise on how to do this, please?

Paul
Comment 4 Paul Thomas 2007-01-12 08:12:44 UTC
Created attachment 12894 [details]
The patch promised above
Comment 5 Paul Thomas 2007-01-14 13:32:07 UTC
I do not seem able to fix the problem with attachments on my machine...

Following yesterday's discussion on the list,

trans-common.c:445

  switch (e->ts.type)
    {
      case BT_INTEGER:
	if (WORDS_BIG_ENDIAN)
	  gfc_conv_mpz_to_integers (e->value.integer,
				    &buffer[0], &buffer[1]);
	else
	  gfc_conv_mpz_to_integers (e->value.integer,
				    &buffer[1], &buffer[0]);
	memcpy (data, buffer, len);
	return;

to replace the BT_INTEGER case in the attachment should do the job.

It needs testing now on 64 bit machines with both endian-nesses.

Brooks, I have reassigned this PR to you; I am very happy to help out/collaborate on it but I think you are right - I just do not have the time to see it through, right now.

Paul 
Comment 6 Paul Thomas 2007-01-14 13:42:40 UTC
Forget the previous; it's wrong!

It does indicate that WORDS_BIG_ENDIAN and friends are available, however.

Paul
Comment 7 Paul Thomas 2007-02-03 16:20:05 UTC
Brooks,

It wasn't fair to deposit this one on you so I have taken it back.

Cheers

Paul 
Comment 8 Brooks Moses 2007-04-23 20:48:06 UTC
*** Bug 31672 has been marked as a duplicate of this bug. ***
Comment 9 Brooks Moses 2007-04-23 20:49:25 UTC
I'm changing the name of this bug to make it a lot easier to find, now that we know what the actual problem is.

Also, PR #31672 contains an excellent testcase for this, which I'll quote here:

----------------------------------------------
function d1mach(i)
implicit none
double precision d1mach,dmach(5)
integer i,large(4),small(4)
equivalence ( dmach(1), small(1) )
equivalence ( dmach(2), large(1) )
data small(1),small(2) / 0,   1048576/
data large(1),large(2) /-1,2146435071/
d1mach = 0.0d0
end function d1mach
----------------------------------------------
Comment 10 Andrew Pinski 2007-04-23 21:50:19 UTC
> brooks@gcc.gnu.org  	2007-04-23 20:51:45  	Priority  	P5  	P2
The release manager is the only one who is able to change the priority.  Changing the Priority back to P5 based on this is a fortran bug so not blocking the release.
Comment 11 Paul Thomas 2007-05-24 08:10:36 UTC
Just to let you all know; I have had a patch ready for this and PR30875 for somewhile.  This was awaiting the commit of Brook's simplify_transfer patch and all the machinery in target-memory.c.  Well, during the wait it suffered a bit of x86_ia64 specific bit-rot, whose cause I just do not see right now. Ia m working on it, though:)

Paul
Comment 12 patchapp@dberlin.org 2007-05-24 13:57:55 UTC
Subject: Bug number PR29786

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2007-05/msg01609.html
Comment 13 Paul Thomas 2007-06-11 22:39:37 UTC
Subject: Bug 29786

Author: pault
Date: Mon Jun 11 22:39:21 2007
New Revision: 125628

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=125628
Log:
2007-06-12  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/29786
	PR fortran/30875
	* trans-common.c (get_init_field): New function.
	(create_common): Call get_init_field for overlapping
	initializers in equivalence blocks.
	* resolve.c (resolve_equivalence_derived, resolve_equivalence):
	Remove constraints on initializers in equivalence blocks.
	* target-memory.c (expr_to_char, gfc_merge_initializers):
	New functions.
	(encode_derived): Add the bit offset to the byte offset to get
	the total offset to the field.
	* target-memory.h : Add prototype for gfc_merge_initializers.


2007-06-12  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/29786
	* gfortran.dg/equiv_7.f90: New test.
	* gfortran.dg/equiv_constraint_7.f90: Change error message.


	PR fortran/30875
	* gfortran.dg/equiv_constraint_5.f90: Correct code and error.

Added:
    trunk/gcc/testsuite/gfortran.dg/equiv_7.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/target-memory.c
    trunk/gcc/fortran/target-memory.h
    trunk/gcc/fortran/trans-common.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/gfortran.dg/equiv_constraint_5.f90
    trunk/gcc/testsuite/gfortran.dg/equiv_constraint_7.f90

Comment 14 Paul Thomas 2007-06-11 22:41:01 UTC
fixed on trunk

Paul