Bug 591635

Summary: gcc internal compiler error: in cdtor_comdat_group, at cp/decl.c:12793
Product: [Fedora] Fedora Reporter: Adam Mitz <mitza>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED RAWHIDE QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: low    
Version: 12CC: jakub, jason
Target Milestone: ---Keywords: Reopened
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2010-05-19 07:43:18 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
tmp file created by gcc internal compiler error
none
gcc 4.4.4 preprocessed source none

Description Adam Mitz 2010-05-12 18:17:28 UTC
Created attachment 413513 [details]
tmp file created by gcc internal compiler error

Description of problem:
internal compiler error: in cdtor_comdat_group, at cp/decl.c:12793

Version-Release number of selected component (if applicable):
gcc version 4.4.3 20100127 (Red Hat 4.4.3-4) (GCC)

How reproducible:
reproducible

Steps to Reproduce:
1. compile attached source
  
Actual results:
In file included from Req_Handler.h:17,
                 from Req_Handler.cpp:3:
Utils/Functors.h: In constructor âCIAO::Config_Handlers::Sequence_Handler<Source, Dest, Dest_Type, Func>::Sequence_Handler(Dest&, CORBA::ULong) [with Source = CIAO::Config_Handlers::Property, Dest = Deployment::Properties, Dest_Type = Deployment::Property, void (& Func)(const Source&, Dest_Type&) = ((void (&)(const CIAO::Config_Handlers::Property&, Deployment::Property&))CIAO::Config_Handlers::Property_Handler::handle_property)]â:
Utils/Functors.h:34: internal compiler error: in cdtor_comdat_group, at cp/decl.c:12793
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.

Expected results:
compilation succeeds

Comment 1 Jakub Jelinek 2010-05-14 12:00:35 UTC
Simplified testcase for -fPIC -O0:

template <typename T> struct S2
{
  typedef const T &t2;
  t2 operator* () const {}
};
template <typename T> struct S3
{
  typedef S2 <T> t5;
};
template <typename T1, typename T2> T2 foo1 (T1 x, T2 y) { y (*x); }
template <class T> struct S4
{
  T &operator* () const;
};
struct S7 {};
struct S8
{
  typedef::S3 <S4 <S7> >::t5 t6;
  t6 m1 () const;
};
template <class T> struct S9
{
  typedef T t3;
  inline t3 &operator[] (unsigned int) {}
};
template <typename T1, typename T2, typename T3, void (&T4) (const T1 &, T3 &)> struct S10
{
  S10 (T2 & x, unsigned int y = 0) : u (x), v (y) {}
  void operator () (const S4 <T1> &x) { T4 (*x, u[v++]); }
  T2 &u;
  unsigned int v;
};
struct S15;
struct S11
{
  static void m3 (const S8 &, S15 &);
};
struct S16;
struct S12;
struct S13
{
  static void m4 (const S7 & desc,S16 & toconfig);
};
typedef S10 <S7, S12, S16, S13::m4> t10;
struct S12: S9 <S16>
{
};
struct S15
{
  S12 p;
};
void S11::m3 (const S8 & x, S15 &y)
{
  foo1 (x.m1 (), t10 (y.p));
}

Comment 2 Jakub Jelinek 2010-05-14 14:05:37 UTC
Unfortunately I can reproduce it only on the redhat/gcc-4_4-branch, seems to be a tree sharing issue to me.
maybe_clone_body is called on S10 ctor and one of the decls is mangled right away, as notice_global_symbol uses DECL_RTL.  That yields
_ZN3S10I2S73S123S16XL_ZN3S132m4ERKS0_RS2_EEEC2ERS1_j
- the last template argument here is:
 <nop_expr 0x7ffff1dbb800
    type <reference_type 0x7ffff1dbed80
        type <function_type 0x7ffff1dbeb40 type <void_type 0x7ffff1e67840 void>
            type_6 QI
            size <integer_cst 0x7ffff1e41780 constant 8>
            unit size <integer_cst 0x7ffff1e417b0 constant 1>
            align 8 symtab 0 alias set -1 canonical type 0x7ffff1dbeb40
            arg-types <tree_list 0x7ffff1dc00c0 value <reference_type 0x7ffff1dbe9c0>
                chain <tree_list 0x7ffff1dc00f0 value <reference_type 0x7ffff1dbea80>
                    chain <tree_list 0x7ffff1e648a0 value <void_type 0x7ffff1e67840 void>>>>
            pointer_to_this <pointer_type 0x7ffff1dbee40> reference_to_this <reference_type 0x7ffff1dbed80>>
        unsigned type_6 DI
        size <integer_cst 0x7ffff1e41b10 constant 64>
        unit size <integer_cst 0x7ffff1e41b40 constant 8>
        align 64 symtab 0 alias set -1 canonical type 0x7ffff1dbed80>
   
    arg 0 <addr_expr 0x7ffff1dbb7c0
        type <pointer_type 0x7ffff1dbee40 type <function_type 0x7ffff1dbeb40>
            unsigned DI size <integer_cst 0x7ffff1e41b10 64> unit size <integer_cst 0x7ffff1e41b40 8>
            align 64 symtab 0 alias set -1 canonical type 0x7ffff1dbee40>
       
        arg 0 <baselink 0x7ffff1dbb780 type <function_type 0x7ffff1dbeb40>
            functions <function_decl 0x7ffff1da5600 m4>
            binfo <tree_binfo 0x7ffff1db7460 type <record_type 0x7ffff1dbe6c0 S13>
               > access_binfo <tree_binfo 0x7ffff1db7460>>>>

Then oeprator () in S10 is tsubsted, and when tsubsting the T4 (...) call, tsubst returns the template argument (which is 0x7ffff1dbb800 and that gets embedded into a CALL_EXPR).  Then cp_gimplify_expr is called and that
modifies that 0x7fffff1dbb800 subtree :
550	    case BASELINK:
551	      *expr_p = BASELINK_FUNCTIONS (*expr_p);
552	      ret = GS_OK;
553	      break;

This means it is now a <nop_expr <addr_expr <function_decl .. > > >
And later on from middle-end DECL_RTL is wanted even on the other ctor.  But at this point it is address of a decl and thus is mangled differently:
_ZN3S10I2S73S123S16LZN3S132m4ERKS0_RS2_EEC1ERS1_j
instead of
_ZN3S10I2S73S123S16XL_ZN3S132m4ERKS0_RS2_EEEC1ERS1_j

The reason why this doesn't ICE in 4.5/4.6 is that the lang_hooks.decls.comdat_group langhook has been removed there, which means that
the comdat group name is created in 4.5 much earlier (still during maybe_clone_body).  While I could fix up this ICE by just making sure DECL_RTL
has been computed when merging ctors or dtors and DECL_ONE_ONLY is set on one of the ctors/dtors:
--- gcc/cp/optimize.c.jj	2009-12-13 21:14:52.000000000 +0100
+++ gcc/cp/optimize.c	2010-05-14 16:02:57.000000000 +0200
@@ -253,6 +253,8 @@ maybe_clone_body (tree fn)
 	  alias = true;
 	  if (DECL_ONE_ONLY (fns[0]) && fns[2])
 	    same_comdat_group = true;
+	  if (DECL_ONE_ONLY (fns[0]))
+	    DECL_ASSEMBLER_NAME (fns[0]);
 	}
 
       /* Build the delete destructor by calling complete destructor
@@ -328,7 +330,12 @@ maybe_clone_body (tree fn)
       BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
       DECL_SAVED_TREE (clone) = NULL;
       if (alias)
-	expand_or_defer_fn_1 (clone);
+	{
+	  expand_or_defer_fn_1 (clone);
+	  /* Mangle it right away.  */
+	  if (DECL_ONE_ONLY (clone))
+	    DECL_ASSEMBLER_NAME (clone);
+	}
       else
 	expand_or_defer_fn (clone);
       first = false;

that doesn't sound like the right fix and I fear that even on the trunk some decl (non-ctor/dtor) might be mangled after unrelated cp_gimplify_expr clobbered a template argument.  This patch fixes it too:
--- gcc/cp/pt.c.jj	2010-05-12 12:56:06.000000000 +0200
+++ gcc/cp/pt.c	2010-05-14 14:59:58.000000000 +0200
@@ -9378,7 +9378,7 @@ tsubst (tree t, tree args, tsubst_flags_
 	      }
 	    else
 	      /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX.  */
-	      return arg;
+	      return unshare_expr (arg);
 	  }
 
 	if (level == 1)
and feels more correct, though neither of those patches are tested yet.

Comment 3 Jakub Jelinek 2010-05-14 14:08:16 UTC
To see this under debugger easiest is to put a
b write_template_arg if node->base.code == NOP_EXPR
and see that in 4.4-RH the argument changed in the third mangling and in 4.5/4.6
just putting a watchpoint on the ADDR_EXPR first operand reveals that it really is modified in place.

Comment 4 Jason Merrill 2010-05-15 03:56:11 UTC
The unshare_expr patch is OK.

Comment 5 Jakub Jelinek 2010-05-17 07:52:51 UTC
Should be fixed in gcc-4.4.4-3.fc{12,13,14}.

Comment 6 Adam Mitz 2010-05-18 20:20:29 UTC
Problem still persists in version
g++ (GCC) 4.4.4 20100514 (Red Hat 4.4.4-3)

In file included from Req_Handler.h:17,
                 from Req_Handler.cpp:3:
Utils/Functors.h: In constructor âCIAO::Config_Handlers::Sequence_Handler<Source, Dest, Dest_Type, Func>::Sequence_Handler(Dest&, CORBA::ULong) [with Source = CIAO::Config_Handlers::Property, Dest = Deployment::Properties, Dest_Type = Deployment::Property, void (& Func)(const Source&, Dest_Type&) = ((void (&)(const CIAO::Config_Handlers::Property&, Deployment::Property&))CIAO::Config_Handlers::Property_Handler::handle_property)]â:
Utils/Functors.h:34: internal compiler error: in cdtor_comdat_group, at cp/decl.c:12846
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
{standard input}: Assembler messages:
{standard input}:2153: Warning: end of file not at end of a line; newline inserted
{standard input}:2672: Warning: group name for SHF_GROUP not specified
Preprocessed source stored into /tmp/cco6J9Ez.out file, please attach this to your bugreport.

Comment 7 Adam Mitz 2010-05-18 20:22:12 UTC
Created attachment 414956 [details]
gcc 4.4.4 preprocessed source

Comment 8 Jakub Jelinek 2010-05-19 07:43:18 UTC
Oops, sorry, 4.4.4-3 didn't have the fix yet.  It is only fixed in gcc-4.4.4-4.{fc{12,13,14},el6}.