Bug 6994

Summary: [3.4 regression] ICE in find_function_data
Product: gcc Reporter: Andreas Schwab <schwab>
Component: c++Assignee: Richard Henderson <rth>
Status: RESOLVED FIXED    
Severity: normal CC: gcc-bugs, janis187, reichelt, rth
Priority: P1 Keywords: ice-on-valid-code
Version: 3.4.0   
Target Milestone: 3.4.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:
Attachments: cube.ii

Description Andreas Schwab 2002-06-11 08:26:02 UTC
Compiler is aborting in find_function_data.

Release:
3.1.1 20020603 (prerelease)

Environment:
i386-suse-linux

How-To-Repeat:
$ gcc cube.ii
cube.ii: In constructor `Cube::Cube(float, float, float, int, int, int)':
cube.ii:28238: Internal compiler error in find_function_data, at function.c:329
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://www.gnu.org/software/gcc/bugs.html> for instructions.
Comment 1 Volker Reichelt 2002-06-12 16:18:03 UTC
From: Reichelt <reichelt@igpm.rwth-aachen.de>
To: adrian@suse.de, gcc-gnats@gcc.gnu.org, gcc-bugs@gcc.gnu.org,
        nobody@gcc.gnu.org, schwab@suse.de
Cc:  
Subject: Re: middle-end/6994: ICE in find_function_data
Date: Wed, 12 Jun 2002 16:18:03 +0200

 Hi,
 
 the bug can be reproduced with the following code snippet
 (just compile with g++ -c):
 
 ----------------------------snip here------------------------
 class A
 {
     A( int );
 };
 
 A::A ( int i )
 {
     int ar[1][i];
 
     ar[0][0] = 0;
 }
 ----------------------------snip here------------------------
 
 The bug is a regression from gcc 2.95.3 (it first appears in gcc 3.0
 and is still present in the main trunk - checked on mips-sgi-irix6.5).
 
 Greetings,
 Volker Reichelt
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6994
 
 

Comment 2 Volker Reichelt 2002-06-12 16:18:03 UTC
From: Reichelt <reichelt@igpm.rwth-aachen.de>
To: adrian@suse.de, gcc-gnats@gcc.gnu.org, gcc-bugs@gcc.gnu.org,
   nobody@gcc.gnu.org, schwab@suse.de
Cc:  
Subject: Re: middle-end/6994: ICE in find_function_data
Date: Wed, 12 Jun 2002 16:18:03 +0200

 Hi,
 
 the bug can be reproduced with the following code snippet
 (just compile with g++ -c):
 
 ----------------------------snip here------------------------
 class A
 {
     A( int );
 };
 
 A::A ( int i )
 {
     int ar[1][i];
 
     ar[0][0] = 0;
 }
 ----------------------------snip here------------------------
 
 The bug is a regression from gcc 2.95.3 (it first appears in gcc 3.0
 and is still present in the main trunk - checked on mips-sgi-irix6.5).
 
 Greetings,
 Volker Reichelt
 
 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6994
 

Comment 3 janis187 2002-10-09 16:00:59 UTC
From: Janis Johnson <janis187@us.ibm.com>
To: gcc-gnats@gcc.gnu.org, gcc-bugs@gcc.gnu.org, adrian@suse.de,
   schwab@suse.de
Cc:  
Subject: Re: middle-end/6994: ICE in find_function_data
Date: Wed, 9 Oct 2002 16:00:59 -0700

 This problem still exists in 3.3 20021008 and 3.2.1 20021009 on
 i686-pc-linux-gnu.  As mentioned earlier, it's a regression from
 GCC 2.95.3.
 
 The PR name ought to be "c++" rather than "middle-end".
 
 At the time of the ICE in find_function_data, 'exp' in expand_expr is
 a SAVE_EXPR whose function context, 'context', is cloned from
 'current_function_decl'.  The code in expand_expr falsely assumes that
 since 'context' is different from 'current_function_decl', 'context' is
 a containing function.  It calls find_function_data just to make sure
 that 'context' is for a containing function, but it's not so that
 function aborts.
 
 I don't where to go from here, but hope that this information will be
 of use to someone familiar with the C++ front end.
 
 Janis

Comment 4 Zack Weinberg 2002-10-09 23:47:31 UTC
From: Zack Weinberg <zack@codesourcery.com>
To: gcc-gnats@gcc.gnu.org, gcc-bugs@gcc.gnu.org, adrian@suse.de,
	schwab@suse.de
Cc:  
Subject: Re: middle-end/6994: ICE in find_function_data (VLA types and SAVE_EXPRs and clones, oh my!)
Date: Wed, 9 Oct 2002 23:47:31 -0700

 On Wed, Oct 09, 2002 at 04:00:59PM -0700, Janis Johnson wrote:
 > At the time of the ICE in find_function_data, 'exp' in expand_expr is
 > a SAVE_EXPR whose function context, 'context', is cloned from
 > 'current_function_decl'.  The code in expand_expr falsely assumes that
 > since 'context' is different from 'current_function_decl', 'context' is
 > a containing function.  It calls find_function_data just to make sure
 > that 'context' is for a containing function, but it's not so that
 > function aborts.
 
 This is a shortened version of the tree structure causing the problem.
 
 <array_ref
     <array_ref
         type <array_type
             size <plus
                 <mult
                     <save 0x401a4040
                         <plus
                             <parm_decl 0x4019fee0 i>
                             <integer_cst -1>>
                         <function_decl A>>
                     <integer_cst 32>>
                  <integer_cst 32>>
             unit size <plus
                 <save 0x401a4320
                     <plus
                         <mult
 			    <parm_decl 0x4019fee0 i>
 			    <integer_cst 4>>
                         <integer_cst -4>>
                     <function_decl A>>
                 <integer_cst 4>>>
        
         <var_decl ar
             size <plus
                 <mult
                     <save 0x401a4900
 			<plus
 			    <parm_decl 0x4019fd90 i>
 			    <integer_cst -1>>
 			<function_decl __base_ctor>>
                     <integer_cst 32>>
                 <integer_cst 32>>
             unit size <plus
                 <save 0x401a49c0
                     <plus
                         <mult
 			    <parm_decl 0x4019fd90 i>
 			    <integer_cst 4>>
 			<integer_cst -4>>
 		    <function_decl __base_ctor>>
                 <integer_cst 4>>>
         <integer_cst 0>>
     <integer_cst 0>>
 
 Please note the presence of SAVE_EXPRs within the size and unit size
 fields of the ARRAY_TYPE at the top.  Note also how very similar those
 fields are to the analogous fields of the VAR_DECL just below.  In
 fact, this ARRAY_TYPE started out life as the type of that VAR_DECL:
 
   int ar[1][i];
 
 where 'i' is a parameter.  The differences are precisely that the
 SAVE_EXPRs and PARM_DECLs inside the type have not been updated to
 point to the right nodes for the clone.  Instead, they are left
 referring to the progenitor, which is what causes find_function_data
 to crash.
 
 The routine responsible for updating SAVE_EXPRs in clones is
 remap_save_expr, in tree-inline.c.  It didn't update those SAVE_EXPRs
 because it was never applied to them.  The reason for this is first
 that copy_trees_r explicitly assumes that TYPEs do not need copying:
 
     /* There's no need to copy types, or anything beneath them.  */
     *walk_subtrees = 0;
 
 This is clearly false for VLA types, such as the one we have here.
 Disabling that is not good enough, though; walk_tree processes neither
 the 'size' nor 'unit size' fields of struct tree_type.  Adding them
 causes this test case to be compiled successfully.  Hence the appended
 patch.
 
 I am not sure if this patch is either correct or complete.  It may be
 that we really do want to enforce the constraint that SAVE_EXPRs or
 other constructs needing fixups never appear inside TYPE nodes; it may
 be that, while some TYPE nodes need copying, others must not be; and
 it may be that we need to consider even more fields of struct
 tree_type in walk_tree.  Comments?
 
 zw
 
 	PR middle-end/6994
 	* tree-inline.c (walk_tree): For nodes of class 't', walk the
 	TYPE_SIZE and TYPE_SIZE_UNIT fields.
 	(copy_tree_r): Do copy types and things beneath them.
 
 	* g++.dg/ext/vla1.C: New test case.
 
 ===================================================================
 Index: tree-inline.c
 --- tree-inline.c	27 Sep 2002 12:48:04 -0000	1.31
 +++ tree-inline.c	10 Oct 2002 06:27:07 -0000
 @@ -1516,6 +1516,11 @@ walk_tree (tp, func, data, htab_)
      {
        WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
      }
 +  else if (TREE_CODE_CLASS (code) == 't')
 +    {
 +      WALK_SUBTREE (TYPE_SIZE (*tp));
 +      WALK_SUBTREE (TYPE_SIZE_UNIT (*tp));
 +    }
  
    result = (*lang_hooks.tree_inlining.walk_subtrees) (tp, &walk_subtrees, func,
  						      data, htab);
 @@ -1683,9 +1688,11 @@ copy_tree_r (tp, walk_subtrees, data)
  	TREE_CHAIN (*tp) = chain;
  #endif /* INLINER_FOR_JAVA */
      }
 +#if 0  /* Not true in the presence of variably-sized types. */
    else if (TREE_CODE_CLASS (code) == 't')
      /* There's no need to copy types, or anything beneath them.  */
      *walk_subtrees = 0;
 +#endif
  
    return NULL_TREE;
  }
 ===================================================================
 Index: testsuite/g++.dg/ext/vla1.C
 --- testsuite/g++.dg/ext/vla1.C	1 Jan 1970 00:00:00 -0000
 +++ testsuite/g++.dg/ext/vla1.C	10 Oct 2002 06:40:29 -0000
 @@ -0,0 +1,16 @@
 +// { dg-do compile }
 +
 +// Check that (a) the VLA declaration provokes an error, and
 +// (b) the compiler does not crash.  See PR middle-end/6994.
 +
 +class A
 +{
 +  A (int);
 +};
 +
 +A::A (int i)
 +{
 +  int ar[1][i];  // { dg-error "variable-size array" }
 +
 +  ar[0][0] = 0;
 +}
Comment 5 Zack Weinberg 2002-10-24 11:21:11 UTC
Responsible-Changed-From-To: unassigned->zack
Responsible-Changed-Why: Working on this.
Comment 6 Zack Weinberg 2002-10-24 11:21:11 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Fix in hand; only needs a bit more testing.
Comment 7 Zack Weinberg 2002-10-25 15:12:51 UTC
State-Changed-From-To: analyzed->closed
State-Changed-Why: Fixed in 3.2.1 and 3.3.
Comment 8 Volker Reichelt 2003-09-26 08:24:55 UTC
Richard's patch

  http://gcc.gnu.org/ml/gcc-cvs/2003-09/msg00666.html

makes the testcase testsuite/g++.dg/ext/vla1.C fail again,
but the underlying problem is a deeper one, according to him
(excerpt from a private mail from Richard):

| My patch merely exposed a previous problem via segv.
| 
| It *should* have been failing before.  I don't know why it wasn't.
| Note that by reverting my change, you get no error on line 12.
| 
| The trees being produced by the c++ front end in this case are
| completely bogus.  It is mere accident that the bogus trees were
| being remapped to error_mark_node, and thus silently ignored by
| the middle-end.
| 
| The front end should be generating an error message and forcing
| error_mark_node there.
Comment 9 Volker Reichelt 2003-09-30 08:46:32 UTC
Richard, you were wondering why vla1.C wasn't failing before:

| It *should* have been failing before.  I don't know why it wasn't.
| Note that by reverting my change, you get no error on line 12.

You probably didn't see the error because you only get it with
"-pedantic" (the variable sized arrays are a GCC extension).
The testsuite seems to have "-pedantic" enabled by default.
So the testsuite was correct then.
Comment 10 Richard Henderson 2003-09-30 18:14:40 UTC
I think this may be a second copy_body problem that Jason has identified,
but has not yet fixed.  I'll make sure to get this done.
Comment 11 Andrew Pinski 2003-10-06 00:36:39 UTC
fixed by:
        * tree-inline.c (remap_type): New.
        (remap_decl): Use it.  Remap DECL_SIZE*.
        (copy_body_r): Use it.
        (walk_tree): Walk TREE_TYPE too.
        (copy_tree_r): Don't walk subtrees of types.
        * tree.c (variably_modified_type_p): Restructure.  Consider integer
        types with non-const bounds variably modified.