Bug 48291 - [4.6/4.7 Regression] [OOP] internal compiler error, new_symbol(): Symbol name too long
Summary: [4.6/4.7 Regression] [OOP] internal compiler error, new_symbol(): Symbol name...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: janus
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2011-03-25 18:08 UTC by Adrian Prantl
Modified: 2011-04-04 18:55 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-03-26 12:10:14


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Adrian Prantl 2011-03-25 18:08:39 UTC
This was tested with 4.6.0-rc2 and svn r171353 on x86_64, Ubuntu 10.4.

$ cat longname.F03

module Overload_AnException_type
  type Overload_AnException_t
  end type Overload_AnException_t
end module Overload_AnException_type


module Overload_AnException
  use Overload_AnException_type
  interface setNote
     module procedure setNote_s
  end interface setNote

contains

  recursive subroutine setNote_s(self, message, exception)
    class(Overload_AnException_t) , intent(in) :: self
  end subroutine setNote_s

end module Overload_AnException


module Overload_AnException_Impl
  use Overload_AnException
  type, extends(Overload_AnException_t) :: Overload_AnException_impl_t
  end type Overload_AnException_impl_t

contains

  subroutine ctor_impl(self, exception)
    type(Overload_AnException_impl_t) :: self
    call setNote(self, 'AnException', exception)
  end subroutine ctor_impl
end module Overload_AnException_Impl


$ gfortran -c longname.F03
longname.F03:33.36:

end module Overload_AnException_Impl
                                    1
Internal Error at (1):
new_symbol(): Symbol name too long


Diagnosis:

fortran/class.c:516
   |514                       /* Construct default initialization variable.
   │516                       sprintf (name, "__def_init_%s", tname);         
  >│517                       gfc_get_symbol (name, ns, &def_init);

This creates the internal symbol name "__def_init_overload_anexception_impl_Overload_anexception_
impl_t" (64 chars)

-> fortran/symbol.c:2529
  2529      if (strlen (name) > GFC_MAX_SYMBOL_LEN) 
  2530        gfc_internal_error ("new_symbol(): Symbol name too long");

which is longer than GFC_MAX_SYMBOL_LEN = 63.

This restriction should not apply in this case, since the Fortran standard allows for names to be up to 63 characters long -- and this particular symbol was generated by the Fortran frontend, not the user.
Comment 1 Jerry DeLisle 2011-03-25 21:32:53 UTC
Since this symbol name is created from a combination of valid names I have to agree we should either eliminate this error altogether or add in some overhead room.  One thing I am curious about is can we get any further nesting of names that would suggest this symbol length could be arbitrarily long.
Comment 2 Adrian Prantl 2011-03-25 22:01:16 UTC
It seems to concatenate at least the name of the module with the name of the derived type:

The culprit is in fortran/class.c:113

/* Create a unique string identifier for a derived type, composed of its name
   and module name. This is used to construct unique names for the class
   containers and vtab symbols.  */

static void
get_unique_type_string (char *string, gfc_symbol *derived)
{
  char dt_name[GFC_MAX_SYMBOL_LEN+1];
  sprintf (dt_name, "%s", derived->name);
  dt_name[0] = TOUPPER (dt_name[0]);
  if (derived->module)
    sprintf (string, "%s_%s", derived->module, dt_name);
  else if (derived->ns->proc_name)
    sprintf (string, "%s_%s", derived->ns->proc_name->name, dt_name);
  else
    sprintf (string, "_%s", dt_name);
}
Comment 3 Adrian Prantl 2011-03-25 22:04:52 UTC
Thus the inelegant solution would be to define GFC_MAX_SYMBOL_LEN to  (63*2)+1+strlen("_def_init").
Comment 4 kargl 2011-03-26 02:43:20 UTC
(In reply to comment #3)
> Thus the inelegant solution would be to define GFC_MAX_SYMBOL_LEN to 
> (63*2)+1+strlen("_def_init").

This won't happen because it doesn't scale.  It's also a known problem.

-- 
steve
Comment 5 janus 2011-03-26 12:10:14 UTC
Thanks for the bug report, Adrian.


(In reply to comment #4)
> > Thus the inelegant solution would be to define GFC_MAX_SYMBOL_LEN to 
> > (63*2)+1+strlen("_def_init").
> 
> This won't happen because it doesn't scale.

Right. Changing GFC_MAX_SYMBOL_LEN will definitely not happen.


> It's also a known problem.

Well, not really. In principle we solve this problem by replacing the derived type name by a hash string if the concatenated name becomes too long (cf. get_unique_hashed_string). However, this does not seem to work in this case (apparently because someone is unable to count properly ;)

Here is the fix:

Index: gcc/fortran/class.c
===================================================================
--- gcc/fortran/class.c (revision 171181)
+++ gcc/fortran/class.c (working copy)
@@ -139,7 +139,7 @@ get_unique_hashed_string (char *string, gfc_symbol
   get_unique_type_string (&tmp[0], derived);
   /* If string is too long, use hash value in hex representation
      (allow for extra decoration, cf. gfc_build_class_symbol)*/
-  if (strlen (tmp) > GFC_MAX_SYMBOL_LEN - 10)
+  if (strlen (tmp) > GFC_MAX_SYMBOL_LEN - 11)
     {
       int h = gfc_hash_value (derived);
       sprintf (string, "%X", h);


With this patch, the test case gives me:

    call setNote(self, 'AnException', exception)
                                                1
Error: There is no specific subroutine for the generic 'setnote' at (1)
Comment 6 janus 2011-03-26 12:17:56 UTC
Here is a reduced (and actually valid) test case:


module Overload_AnException_Impl
  type :: Overload_AnException_impl_t
  end type
contains
  subroutine ctor_impl(self)
    class(Overload_AnException_impl_t) :: self
  end subroutine
end module 


Moreover, this beast is a 4.6 regression. 4.5 worked fine.
Comment 7 Jerry DeLisle 2011-03-26 15:23:05 UTC
Your patch is approved after regression testing and thanks for getting on it so quickly.  Maybe the release managers might want to sneak it in to 4.6.0 but perhaps its too late. Certainly 4.6.1.  ;)
Comment 8 janus 2011-03-26 17:34:40 UTC
(In reply to comment #7)
> Your patch is approved after regression testing and thanks for getting on it so
> quickly.

Thanks. Regtest was successful. Will commit shortly.


> Maybe the release managers might want to sneak it in to 4.6.0 but
> perhaps its too late.

It seems the tarballs have hit the servers already ...


> Certainly 4.6.1.  ;)

Yes.
Comment 9 janus 2011-03-26 18:39:19 UTC
Author: janus
Date: Sat Mar 26 18:39:14 2011
New Revision: 171559

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171559
Log:
2011-03-26  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/48291
	* class.c (get_unique_hashed_string): Adjust maximum allowable length
	for unique type string.

2011-03-26  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/48291
	* gfortran.dg/class_42.f03: New.

Added:
    trunk/gcc/testsuite/gfortran.dg/class_42.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/class.c
    trunk/gcc/testsuite/ChangeLog
Comment 10 janus 2011-04-04 18:53:37 UTC
Author: janus
Date: Mon Apr  4 18:53:34 2011
New Revision: 171950

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=171950
Log:
2011-04-04  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/48291
	* class.c (get_unique_hashed_string): Adjust maximum allowable length
	for unique type string.

2011-04-04  Janus Weil  <janus@gcc.gnu.org>

	PR fortran/48291
	* gfortran.dg/class_42.f03: New.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/gfortran.dg/class_42.f03
Modified:
    branches/gcc-4_6-branch/gcc/fortran/ChangeLog
    branches/gcc-4_6-branch/gcc/fortran/class.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Comment 11 janus 2011-04-04 18:54:41 UTC
Fixed on trunk and 4.6. Closing.
Comment 12 janus 2011-04-04 18:55:59 UTC
(In reply to comment #11)
> Closing.

... for real.