Bug 29209

Summary: ICE optimizing passing long double to abstract method while in other abstract's impl
Product: gcc Reporter: Michael Haubenwallner <michael.haubenwallner>
Component: middle-endAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: bugzilla-gcc, danglin, debian-gcc, gcc-bugs, michael.haubenwallner, pinskia, sje, tbm, thomas.g.girard
Priority: P3 Keywords: ice-on-valid-code
Version: 4.1.1   
Target Milestone: ---   
See Also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40505
Host: hppa2.0w-hp-hpux11.11 Target: hppa2.0w-hp-hpux11.11
Build: hppa2.0w-hp-hpux11.11 Known to work:
Known to fail: Last reconfirmed: 2009-05-05 17:54:27
Bug Depends on: 29182    
Bug Blocks:    

Description Michael Haubenwallner 2006-09-25 08:59:56 UTC
Another ICE with long double, now with optimization only:

$ cat aa.cc
class DataEncoder {
public:
        virtual void put_longdouble(long double) = 0;
};

class DataOutputStream {
public:
        virtual void write_longdouble(long double value) = 0;
};

class DataOutputStream_impl : virtual public DataOutputStream
{
public:
        void write_longdouble(long double value);
private:
        DataEncoder *ec;
};

void DataOutputStream_impl::write_longdouble(long double value)
{
        ec->put_longdouble(value);
}

$ g++ aa.cc -c -O2
aa.cc: In member function 'void DataOutputStream_impl::_ZTv0_n12_N21DataOutputStream_impl16write_longdoubleEe(long double)':
aa.cc:21: internal compiler error: in expand_expr_addr_expr_1, at expr.c:6336
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
$ g++ -v
Using built-in specs.
Target: hppa2.0w-hp-hpux11.11
Configured with: /mnt/toolsjunk/snapshot/src/sasrvb/toolsbox-3.5.1.6pre.20060924/buildroot/gcc/gcc-4.1.1/configure --enable-threads=posix --with-gnu-as --with-as=/tools/snapshot/toolsbox-3.5.1.6pre.20060924/hppa2.0w-hp-hpux11.11/hppa2.0w-hp-hpux11.11/bin/as --without-gnu-ld --with-local-prefix=/tools/snapshot/toolsbox-3.5.1.6pre.20060924/hppa2.0w-hp-hpux11.11 --disable-nls --enable-version-specific-runtime-libs --prefix=/tools/snapshot/toolsbox-3.5.1.6pre.20060924/hppa2.0w-hp-hpux11.11
Thread model: posix
gcc version 4.1.1
$
Comment 1 Michael Haubenwallner 2006-09-25 09:02:15 UTC
Two ICE's while building one source file, first one is from Bug#29182.
Comment 2 Andrew Pinski 2006-09-26 07:10:04 UTC

*** This bug has been marked as a duplicate of 26957 ***
Comment 3 Michael Haubenwallner 2006-09-26 07:28:35 UTC
Err, the patch from Bug#26957#c16 is already applied and works.
This is another ICE.

Difference in testcase is that the second ICE occurs when the 'long double value' is passed to another virtual method of another abstract objectptr.

In the first one, the body of DataOutputStream_impl::write_longdouble() is empty, while here it is not.

And, the second one does occur with any optimization >= -O1, not with -O0.
Comment 4 John David Anglin 2006-10-10 23:00:50 UTC
This bug is still present on trunk:

-bash-2.05b$ /test/gnu/gcc/objdir/gcc/g++ -B/test/gnu/gcc/objdir/gcc/ -S -O2 p>
pr29209.cc: In member function 'void DataOutputStream_impl::_ZTv0_n12_N21DataOutputStream_impl16write_longdoubleEe(long double)':
pr29209.cc:21: internal compiler error: in expand_expr_addr_expr_1, at expr.c:6506
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
<c/g++ -B/test/gnu/gcc/objdir/gcc/ -S -O2 pr29209.cc -v > xxx.sh 2>&1

Breakpoint 1, expand_expr_addr_expr_1 (exp=0x0, target=0x76, tmode=1431655765,
    modifier=118) at ../../gcc/gcc/expr.c:6458
6458      if (TREE_CODE (exp) == CONSTRUCTOR
(gdb) bt
#0  expand_expr_addr_expr_1 (exp=0x0, target=0x76, tmode=1431655765,
    modifier=118) at ../../gcc/gcc/expr.c:6458
#1  0x0028b014 in expand_expr_real_1 (exp=0x7ae69760, target=0x0,
    tmode=SImode, modifier=EXPAND_NORMAL, alt_rtl=0x0)
    at ../../gcc/gcc/expr.c:6593
#2  0x002941fc in expand_expr_real (exp=0x7ae69760, target=0x0,
    tmode=VOIDmode, modifier=EXPAND_NORMAL, alt_rtl=0x0)
    at ../../gcc/gcc/expr.c:6706
#3  0x00240e9c in expand_call (exp=0x7adc07f8, target=0x0, ignore=1)
    at ../../gcc/gcc/expr.h:499
#4  0x0028c054 in expand_expr_real_1 (exp=0x7adc07f8, target=0x7adb5210,
    tmode=VOIDmode, modifier=EXPAND_NORMAL, alt_rtl=0x0)
    at ../../gcc/gcc/expr.c:7671
#5  0x00294110 in expand_expr_real (exp=0x7adc07f8, target=0x0,
    tmode=VOIDmode, modifier=EXPAND_NORMAL, alt_rtl=0x0)
    at ../../gcc/gcc/expr.c:6700
#6  0x003322dc in expand_expr_stmt (exp=0x7adc07f8)
    at ../../gcc/gcc/stmt.c:1356
#7  0x00530f8c in expand_gimple_basic_block (bb=0x7adcc990)
    at ../../gcc/gcc/cfgexpand.c:1199
#8  0x005323ac in tree_expand_cfg () at ../../gcc/gcc/cfgexpand.c:1644
#9  0x0037136c in execute_one_pass (pass=0x40018070)
    at ../../gcc/gcc/passes.c:870
---Type <return> to continue, or q <return> to quit---
#10 0x0037150c in execute_pass_list (pass=0x40018070)
    at ../../gcc/gcc/passes.c:917
#11 0x001c69f8 in tree_rest_of_compilation (fndecl=0x7ae60310)
    at ../../gcc/gcc/tree-optimize.c:463
#12 0x00121ca4 in expand_body (fn=0x7ae60310)
    at ../../gcc/gcc/cp/semantics.c:3068
#13 0x00117a8c in use_thunk (thunk_fndecl=0x7ae60310, emit_p=0 '\0')
    at ../../gcc/gcc/cp/method.c:524
#14 0x00121c2c in expand_body (fn=0x7ae602a0)
    at ../../gcc/gcc/cp/semantics.c:3021
#15 0x00397624 in cgraph_expand_function (node=0x7ae603f0)
    at ../../gcc/gcc/cgraphunit.c:1233
#16 0x0039aaf4 in cgraph_optimize () at ../../gcc/gcc/cgraphunit.c:1298
#17 0x000bdcbc in cp_finish_file () at ../../gcc/gcc/cp/decl2.c:3344
#18 0x0002d2ac in finish_file () at ../../gcc/gcc/cp/cp-lang.c:144
#19 0x00191cc4 in c_common_parse_file (set_yydebug=2061227104)
    at ../../gcc/gcc/c-opts.c:1176
#20 0x0033d49c in toplev_main (argc=1073937672, argv=0x1)
    at ../../gcc/gcc/toplev.c:1033
#21 0x001a2b24 in main (argc=2061227104, argv=0x0) at ../../gcc/gcc/main.c:35
Comment 5 Martin Michlmayr 2007-02-03 09:45:33 UTC
I don't see this with Linux on HPPA hardware.  Steve Ellcey, can you try on HPUX please?
Comment 6 dave 2007-02-03 14:47:50 UTC
Subject: Re:  ICE optimizing passing long double to abstract method while in other abstract's impl

> ------- Comment #5 from tbm at cyrius dot com  2007-02-03 09:45 -------
> I don't see this with Linux on HPPA hardware.  Steve Ellcey, can you try on
> HPUX please?

The treatment of long doubles on HPUX and Linux is different.  Long
doubles are 128-bit IEEE format on HPUX.  They are 64-bit IEEE format
on Linux (i.e., same as double).  Arguments larger than 64 bits are
passed by indirect reference.  Thus, the 128-bit format is always passed
by reference.  Smaller arguments are passed by value.

Dave
Comment 7 dave 2007-02-03 15:16:42 UTC
Subject: Re:  ICE optimizing passing long double to abstract method while in other abstract's impl

> ------- Comment #5 from tbm at cyrius dot com  2007-02-03 09:45 -------
> I don't see this with Linux on HPPA hardware.  Steve Ellcey, can you try on
> HPUX please?

I can no longer duplicate this using 4.1.1 (I recently rebuilt it
with an updated version of gmp/mpfr).  Trunk also doesn't ICE.
However, I see ICEs with 4.0.0, 4.0.1, 4.0.2, 4.0.3, 4.0.4 and
4.1.0 in make_decl_rtl:

-bash-2.05b$ /opt/gnu/gcc/gcc-4.1.0/bin/g++ -c -O3 pr29209-1.cc
pr29209-1.cc: In member function 'void DataOutputStream_impl::_ZTv0_n12_N21DataOutputStream_impl16write_longdoubleEe(long double)':
pr29209-1.cc:21: internal compiler error: in make_decl_rtl, at varasm.c:890
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.

Dave
Comment 8 dave 2007-02-04 01:50:57 UTC
Subject: Re:  ICE optimizing passing long double to abstract method while in other abstract's impl

> > ------- Comment #5 from tbm at cyrius dot com  2007-02-03 09:45 -------
> > I don't see this with Linux on HPPA hardware.  Steve Ellcey, can you try on
> > HPUX please?
> 
> I can no longer duplicate this using 4.1.1 (I recently rebuilt it
> with an updated version of gmp/mpfr).  Trunk also doesn't ICE.

Ignore the above.  Whether or not an ICE occurs depends to some extent
on checking being enabled.  With checking enabled, I see this on 4.1
and the trunk.

The ICE is here:

          result = expand_expr (exp, target, tmode,
				modifier == EXPAND_INITIALIZER
				? EXPAND_INITIALIZER : EXPAND_CONST_ADDRESS);

          /* If the DECL isn't in memory, then the DECL wasn't properly
	     marked TREE_ADDRESSABLE, which will be either a front-end
	     or a tree optimizer bug.  */
	 gcc_assert (MEM_P (result));

This is "result":

(gdb) p debug_rtx ($ret0)
(reg/v:TF 96 [ value ])
(gdb) p debug_tree (exp)
 <parm_decl 7adede10 value
    type <real_type 7adf2b40 long double TF
	size <integer_cst 7ade1540 constant invariant 128>
	unit size <integer_cst 7ade1558 constant invariant 16>
	align 64 symtab 0 alias set 18 precision 128
	pointer_to_this <pointer_type 7adf2c60>>
    addressable used TF file pr29209.cc line 19 size <integer_cst 7ade1540 128> unit size <integer_cst 7ade1558 16>
    align 64 context <function_decl 7ae66380 _ZTv0_n12_N21DataOutputStream_impl16write_longdoubleEe> initial <real_type 7adf2b40 long double>
    (reg/v:TF 96 [ value ]) arg-type <real_type 7adf2b40 long double>
    incoming-rtl (reg:SI 25 %r25 [ value ])>
(gdb) bt
#0  expand_expr_addr_expr_1 (exp=0x7adede10, target=0x0, tmode=SImode,
    modifier=EXPAND_NORMAL) at ../../gcc/gcc/expr.c:6336
#1  0x0018c9a8 in expand_expr_real_1 (exp=0x7ae65f40, target=0x0,
    tmode=SImode, modifier=EXPAND_NORMAL, alt_rtl=0x0)
    at ../../gcc/gcc/expr.c:6423
#2  0x00190c2c in expand_expr_real (exp=0x7ae65f40, target=0x0,
    tmode=VOIDmode, modifier=EXPAND_NORMAL, alt_rtl=0x0)
    at ../../gcc/gcc/expr.c:6536
#3  0x001539bc in expand_call (exp=0x7adef7a8, target=0x0, ignore=1)
    at ../../gcc/gcc/expr.h:493
#4  0x0018dd74 in expand_expr_real_1 (exp=0x7adef7a8, target=0x7ade5210,
    tmode=VOIDmode, modifier=EXPAND_NORMAL, alt_rtl=0x0)
    at ../../gcc/gcc/expr.c:7493
#5  0x00190b3c in expand_expr_real (exp=0x7adef7a8, target=0x0,
    tmode=VOIDmode, modifier=EXPAND_NORMAL, alt_rtl=0x0)
    at ../../gcc/gcc/expr.c:6530
#6  0x001ff1ac in expand_expr_stmt (exp=0x7adef7a8)
    at ../../gcc/gcc/stmt.c:1357
#7  0x0039b720 in expand_gimple_basic_block (bb=0x7ae94000, dump_file=0xc)
    at ../../gcc/gcc/cfgexpand.c:1188
#8  0x0039c840 in tree_expand_cfg () at ../../gcc/gcc/cfgexpand.c:1626
#9  0x00227460 in execute_one_pass (pass=0x40014e28)
    at ../../gcc/gcc/passes.c:827
...

In frame 1, exp looks like this:

(gdb) p debug_tree (exp)
 <addr_expr 7ae65f40
    type <pointer_type 7adf2c60
	type <real_type 7adf2b40 long double TF
	     size <integer_cst 7ade1540 constant invariant 128>
	     unit size <integer_cst 7ade1558 constant invariant 16>
	     align 64 symtab 0 alias set 18 precision 128
	     pointer_to_this <pointer_type 7adf2c60>>
	 unsigned SI
	 size <integer_cst 7ade12d0 constant invariant 32>
	 unit size <integer_cst 7ade1060 constant invariant 4>
	 align 32 symtab 0 alias set -1>
     invariant
     arg 0 <parm_decl 7adede10 value type <real_type 7adf2b40 long double>
	 addressable used TF file pr29209.cc line 19 size <integer_cst 7ade1540 128> unit size <integer_cst 7ade1558 16>
	 align 64 context <function_decl 7ae66380 _ZTv0_n12_N21DataOutputStream_impl16write_longdoubleEe> initial <real_type 7adf2b40 long double>
	 (reg/v:TF 96 [ value ]) arg-type <real_type 7adf2b40 long double>
	 incoming-rtl (reg:SI 25 %r25 [ value ])>>

The ICE occurs in the expand pass.

Dave
Comment 9 Martin Michlmayr 2007-10-19 21:10:04 UTC
(In reply to comment #8)
> Whether or not an ICE occurs depends to some extent
> on checking being enabled.  With checking enabled, I see this on 4.1
> and the trunk.
> 
> The ICE is here:
> 
>           result = expand_expr (exp, target, tmode,
>                                 modifier == EXPAND_INITIALIZER
>                                 ? EXPAND_INITIALIZER : EXPAND_CONST_ADDRESS);
> 
>           /* If the DECL isn't in memory, then the DECL wasn't properly
>              marked TREE_ADDRESSABLE, which will be either a front-end
>              or a tree optimizer bug.  */
>          gcc_assert (MEM_P (result));

Julien Cristau just reported an ICE with gcc 4.2 on hppa and I tracked it down
to the same piece of quote you're quoting above.  Note that my reduced testcase
produces an ICE with gcc 4.1, 4.2 and trunk.  Dave, can you take a look at it
please?

The following testcase requires -O:

paer% gcc-4.2 -c -O2 basematrix.cc
basematrix.cc: In member function ‘void S_BaseMatrix<complex<double> >::_ZTv0_n12_N12S_BaseMatrixI7complexIdEE12MultTransAddES1_(Complex)’:
basematrix.cc:33: internal compiler error: in expand_expr_addr_expr_1, at expr.c:6554
Please submit a full bug report,
with preprocessed source if appropriate.


Testcase:

/* Testcase by Martin Michlmayr <tbm@cyrius.com> */

template < typename _CharT > class basic_stringstream;
typedef basic_stringstream < char >stringstream;

template < typename _CharT > class basic_ios
{
};
template < typename _CharT > class basic_stringstream:
 virtual public basic_ios < _CharT >
{
};

template < typename _Tp > class complex;
template <> struct complex <double >
{
    __complex__ double _M_value;
};
typedef complex < double >Complex;

class BaseMatrix
{
    virtual void MultTransAdd (Complex s);
};
template < typename SCAL > class S_BaseMatrix:virtual public BaseMatrix
{
};
template < > class S_BaseMatrix < Complex >:virtual public BaseMatrix
{
    virtual void MultTransAdd (Complex s);
};
void S_BaseMatrix < Complex >::MultTransAdd (Complex s) {
    stringstream err;
}
Comment 10 Martin Michlmayr 2007-10-19 21:12:45 UTC
I forgot to mention that this is on Linux (Debian).
Comment 11 dave 2007-11-07 02:48:58 UTC
Subject: Re:  ICE optimizing passing long double to abstract method while in other abstract's impl

> ------- Comment #10 from tbm at cyrius dot com  2007-10-19 21:12 -------
> I forgot to mention that this is on Linux (Debian).

At the moment, I still see this with 4.2 but not on the trunk.  There's
some issue with taking the address of a DCmode var_decl.

Dave
Comment 12 Steve Ellcey 2009-05-05 17:54:27 UTC
I retested the test case in comment#1 on a hppa2.0w-hp-hpux11.11 box and it still gives an ICE with 4.4.0 and with ToT (r147128).  I don't have a PA linux box so I did not test the example from comment #9 on a linux box.
Comment 13 Andrew Pinski 2022-01-02 05:26:11 UTC
(In reply to Martin Michlmayr from comment #9)
> paer% gcc-4.2 -c -O2 basematrix.cc
> basematrix.cc: In member function ‘void S_BaseMatrix<complex<double>
> >::_ZTv0_n12_N12S_BaseMatrixI7complexIdEE12MultTransAddES1_(Complex)’:
> basematrix.cc:33: internal compiler error: in expand_expr_addr_expr_1, at
> expr.c:6554
> Please submit a full bug report,
> with preprocessed source if appropriate.


This one is reported as PR 40505 now.