This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] Re: [C++] SEGV in mapcar() with a CALL_EXPR


OK, I sat down with this for a while, and I came up with a patch.

As I suspected below, the problem seems to be that there IS an rtl in
the slot in question, which just happens to satisfy
TREE_CODE (TREE_OPERAND (t, 2)) == TREE_LIST.  I took an unused
lang_flag (TREE_LANG_FLAG_5 in this case), and used it to flag whether
or not the node was actually supposed to contain a tree.

To be honest, I'm more surprised that this reuse of operand 2 and
preexpand_calls(), which is where the RTL got filled in, don't kill
each other more often.

One of the other flags could probably be reused instead of adding a
new one.  I didn't want to try to figure out which flag, if any, would
never be applicable to these CALL_EXPRs.

Also, where mapcar now says:
        if (TREE_OPERAND (t, 2)
          && CALL_EXPR_RTL_IS_TREE (t)
          && TREE_CODE (TREE_OPERAND (t, 2)) == TREE_LIST)
the last check is redundant - perhaps enable-checking should flag an
error if the operand is NOT a list, because it certainly should be.

Passes 'make check' on powerpc-*-linux-gnu with no regressions.


For cp/ChangeLog:

Fri Aug 6 18:43:19 EDT 1999  Daniel Jacobowitz  <dan@debian.org>
	* cp-tree.h (CALL_EXPR_RTL_IS_TREE): Add and document.

	* lex.c (make_call_declarator): Set CALL_EXPR_RTL_IS_TREE
	if appropriate.
	(set_quals_and_spec): Likewise.

	* tree.c (mapcar): Check CALL_EXPR_RTL_IS_TREE.



On Wed, Aug 04, 1999 at 01:19:59PM -0400, Daniel Jacobowitz wrote:
> Attached is a testcase for this elusive little segfault on
> powerpc-*-linux-gnu.  It's exceedingly sensitive - the problem
> disappeared if I used an absolute -I path instead of a relative one. 
> And now that I have looked at what is going on, I think I understand
> why.
> 
> In cp/tree.c:mapcar, around line 1887, is this code snippet:
> 
>       /* tree.def says that operand two is RTL, but
>          make_call_declarator puts trees in there.  */
>       if (TREE_OPERAND (t, 2)
>           && TREE_CODE (TREE_OPERAND (t, 2)) == TREE_LIST)
>         TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func);
>       else
>         TREE_OPERAND (t, 2) = NULL_TREE;
>       return t;
> 
> The problem is, from what I can tell, that there is actually an RTL in
> this slot which purely by coincidence meets that condition.  In this
> case, from what I can tell, the rtl is (reg:SI 85).
> 
> More gory details:
> 
> (gdb) p debug_tree(t)
>  <call_expr 0x1033afb8
>     type <reference_type 0x106883c8
>         type <record_type 0x1065d440 Header allocated from permanent_obstack
>             permanent needs-constructing type_1 type_5 BLK
>             size <integer_cst 0x1069ef58 constant permanent 68256>
>             align 32 symtab 0 alias set 0 fields <field_decl 0x10692968 Signature> context <record_type 0x1065d180 pkgCache>
>            needs-constructor X() X(constX&) this=(X&) n_parents 0 use_template=0 interface-only
>             member-functions <tree_vec 0x10686548 allocated from permanent_obstack
>                 permanent
>                 elt 0 <overload 0x1069ed48>
>                 elt 2 <function_decl 0x1069e1d0 CheckSizes>
>                 elt 3 <function_decl 0x1069ebd0 __as>>
>             pointer_to_this <pointer_type 0x1065d4f0> reference_to_this <reference_type 0x106883c8> chain <type_decl 0x1065d598 Header>>
>         allocated from permanent_obstack
>         unsigned permanent SI
>         size <integer_cst 0x10344c80 constant permanent 32>
>         align 32 symtab 0 alias set -1>
>     allocated from function obstack
>     side-effects
>     arg 0 <addr_expr 0x1033afd8
>         type <pointer_type 0x10753098 type <method_type 0x10688498>
>             allocated from permanent_obstack
>             unsigned permanent SI size <integer_cst 0x10344c80 32>
>             align 32 symtab 0 alias set -1>
>         allocated from function obstack
> 
>         arg 0 <function_decl 0x10688520 Head type <method_type 0x10688498>
>             allocated from permanent_obstack
>             used permanent public static external inline defer-output decl_5 SI file ../build/include/apt-pkg/pkgcache.h line 94
>             frame_size 0 context <record_type 0x1065d180 pkgCache> arguments <parm_decl 0x106885b0 this>
>  result <result_decl 0x10692328> initial <block 0x10699400>
>             decl-main-variant 0x10688520
>             (mem/f:SI (symbol_ref:SI ("Head__8pkgCache")) 550)
>             saved-insns 0x10699438 chain <function_decl 0x106887c8 PkgBegin>>>
>     arg 1 <tree_list 0x1033aff0 allocated from function obstack
> 
>         value <nop_expr 0x1033b008 type <pointer_type 0x1065d230>
>             allocated from function obstack
> 
>             arg 0 <convert_expr 0x1033b020 type <pointer_type 0x10787698>
>                 allocated from function obstack
>                 arg 0 <parm_decl 0x10824860 Cache>>>>
>     rtl 2 (reg:SI 85)
> >
> $36 = void
> (gdb) list
> 1886
> 1887          /* tree.def says that operand two is RTL, but
> 1888             make_call_declarator puts trees in there.  */
> 1889          if (TREE_OPERAND (t, 2)
> 1890              && TREE_CODE (TREE_OPERAND (t, 2)) == TREE_LIST)
> 1891            TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func);
> 1892          else
> 1893            TREE_OPERAND (t, 2) = NULL_TREE;
> 1894          return t;
> 1895
> (gdb) where
> #0  mapcar (t=0x1033afb8, func=0x1025b290 <permanent_p>) at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1891
> ...
> (gdb) cont
> Continuing.
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x1025b2a4 in permanent_p (t=0x220000) at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1998
> 1998      return TREE_PERMANENT (t) ? t : NULL_TREE;
> (gdb) bt
> #0  0x1025b2a4 in permanent_p (t=0x220000) at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1998
> #1  0x1025a6e0 in mapcar (t=0x220000, func=0x1025b290 <permanent_p>)
>     at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1743
> #2  0x1025a8ac in mapcar (t=0x1033b038, func=0x1025b290 <permanent_p>)
>     at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1790
> #3  0x1025abc0 in mapcar (t=0x1033afb8, func=0x1025b290 <permanent_p>)
>     at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1891
> #4  0x1025ac24 in mapcar (t=0x1033afa0, func=0x1025b290 <permanent_p>)
>     at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1908
> #5  0x1025ac24 in mapcar (t=0x1033af88, func=0x1025b290 <permanent_p>)
>     at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1908
> #6  0x1025ac24 in mapcar (t=0x1033af70, func=0x1025b290 <permanent_p>)
>     at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1908
> #7  0x1025aab8 in mapcar (t=0x1033af50, func=0x1025b290 <permanent_p>)
>     at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1836
> #8  0x1025aaf0 in mapcar (t=0x1033af38, func=0x1025b290 <permanent_p>)
>     at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1877
> #9  0x1025aaf0 in mapcar (t=0x1033af20, func=0x1025b290 <permanent_p>)
>     at /usr/src/gcc/gcc-2.95/gcc/cp/tree.c:1877
> #10 0x10246528 in build_new_1 (exp=0x1033be98) at /usr/src/gcc/gcc-2.95/gcc/cp/init.c:2470
> #11 0x101f42f8 in cplus_expand_expr (exp=0x1033be98, target=0x1025b290, tmode=VOIDmode, 
>     modifier=EXPAND_NORMAL) at /usr/src/gcc/gcc-2.95/gcc/cp/expr.c:247
> #12 0x10047bc0 in expand_expr (exp=0x1033be98, target=0x0, tmode=VOIDmode, modifier=EXPAND_NORMAL)
>     at /usr/src/gcc/gcc-2.95/gcc/expr.c:8226
> #13 0x10045158 in expand_expr (exp=0x1033bed0, target=0x0, tmode=SImode, modifier=EXPAND_NORMAL)
>     at /usr/src/gcc/gcc-2.95/gcc/expr.c:6869
> #14 0x1003f2ec in store_expr (exp=0x1033bed0, target=0x107dd0f8, want_value=0)
>     at /usr/src/gcc/gcc-2.95/gcc/expr.c:3715
> #15 0x100415c4 in store_field (target=0x107dd0d8, bitsize=32, bitpos=0, mode=SImode, exp=0x1033bed0, 
>     value_mode=VOIDmode, unsignedp=1, align=4, total_size=20, alias_set=802)
>     at /usr/src/gcc/gcc-2.95/gcc/expr.c:4773
> #16 0x1003eaf8 in expand_assignment (to=0x1033bbe0, from=0x1033bed0, want_value=0, 
>     suggest_reg=271827272) at /usr/src/gcc/gcc-2.95/gcc/expr.c:3413
> #17 0x10047478 in expand_expr (exp=0x1033bee8, target=0x1033bed0, tmode=VOIDmode, 
>     modifier=EXPAND_NORMAL) at /usr/src/gcc/gcc-2.95/gcc/expr.c:7949
> #18 0x1002dd90 in expand_expr_stmt (exp=0x1033bee8) at /usr/src/gcc/gcc-2.95/gcc/stmt.c:1669
> #19 0x101f2d40 in cplus_expand_expr_stmt (exp=0x1033bee8) at /usr/src/gcc/gcc-2.95/gcc/cp/decl.c:14855
> #20 0x1025448c in finish_expr_stmt (expr=0x1033bee8) at /usr/src/gcc/gcc-2.95/gcc/cp/semantics.c:82
> #21 0x1022a90c in yyparse () at parse.y:3282
> #22 0x1000517c in compile_file ()
> #23 0x1000a090 in main ()
> #24 0xfedbe94 in   ()
> 
> 
> 
> And last but not least,
>         .ident  "GCC: (GNU) 2.95 19990728 (release)"



Dan

/--------------------------------\  /--------------------------------\
|       Daniel Jacobowitz        |__|        SCS Class of 2002       |
|   Debian GNU/Linux Developer    __    Carnegie Mellon University   |
|         dan@debian.org         |  |       dmj+@andrew.cmu.edu      |
\--------------------------------/  \--------------------------------/
diff -rcp ../egcs/for-unstable/gcc-2.95/gcc/cp/cp-tree.h gcc-2.95/gcc/cp/cp-tree.h
*** ../egcs/for-unstable/gcc-2.95/gcc/cp/cp-tree.h	Thu Jun 24 09:16:17 1999
--- gcc-2.95/gcc/cp/cp-tree.h	Fri Aug  6 17:41:45 1999
*************** Boston, MA 02111-1307, USA.  */
*** 52,58 ****
     4: BINFO_NEW_VTABLE_MARKED.
        TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
            or FIELD_DECL).
!    5: Not used.
     6: Not used.
  
     Usage of TYPE_LANG_FLAG_?:
--- 52,58 ----
     4: BINFO_NEW_VTABLE_MARKED.
        TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR,
            or FIELD_DECL).
!    5: CALL_EXPR_RTL_IS_TREE.
     6: Not used.
  
     Usage of TYPE_LANG_FLAG_?:
*************** extern int flag_new_for_scope;
*** 1614,1619 ****
--- 1614,1622 ----
  
  /* Nonzero for _TYPE means that the _TYPE defines a destructor.  */
  #define TYPE_HAS_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_2(NODE))
+ 
+ /* Nonzero for CALL_EXPR means that operands[2] is a cv_qualifier tree */
+ #define CALL_EXPR_RTL_IS_TREE(NODE) (TREE_LANG_FLAG_5(NODE))
  
  #if 0
  /* Nonzero for _TYPE node means that creating an object of this type
diff -rcp ../egcs/for-unstable/gcc-2.95/gcc/cp/lex.c gcc-2.95/gcc/cp/lex.c
*** ../egcs/for-unstable/gcc-2.95/gcc/cp/lex.c	Thu Jun 24 09:16:26 1999
--- gcc-2.95/gcc/cp/lex.c	Fri Aug  6 16:14:25 1999
*************** make_call_declarator (target, parms, cv_
*** 226,231 ****
--- 226,233 ----
       tree target, parms, cv_qualifiers, exception_specification;
  {
    target = build_parse_node (CALL_EXPR, target, parms, cv_qualifiers);
+   if (cv_qualifiers != NULL_TREE)
+     CALL_EXPR_RTL_IS_TREE (target) = 1;
    TREE_TYPE (target) = exception_specification;
    return target;
  }
*************** set_quals_and_spec (call_declarator, cv_
*** 235,240 ****
--- 237,246 ----
       tree call_declarator, cv_qualifiers, exception_specification;
  {
    TREE_OPERAND (call_declarator, 2) = cv_qualifiers;
+   if (cv_qualifiers != NULL_TREE)
+     CALL_EXPR_RTL_IS_TREE (call_declarator) = 1;
+   else
+     CALL_EXPR_RTL_IS_TREE (call_declarator) = 0;
    TREE_TYPE (call_declarator) = exception_specification;
  }
  
diff -rcp ../egcs/for-unstable/gcc-2.95/gcc/cp/tree.c gcc-2.95/gcc/cp/tree.c
*** ../egcs/for-unstable/gcc-2.95/gcc/cp/tree.c	Thu Jun 24 09:16:27 1999
--- gcc-2.95/gcc/cp/tree.c	Fri Aug  6 16:08:20 1999
*************** mapcar (t, func)
*** 1887,1892 ****
--- 1887,1893 ----
        /* tree.def says that operand two is RTL, but
  	 make_call_declarator puts trees in there.  */
        if (TREE_OPERAND (t, 2)
+ 	  && CALL_EXPR_RTL_IS_TREE (t)
  	  && TREE_CODE (TREE_OPERAND (t, 2)) == TREE_LIST)
  	TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func);
        else

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]