I don't have time to investigate this further right now, but for the attached testcase, I get this ICE with mainline as of this morning: deal.II/lac> c++ -c sparse_direct.ii source/sparse_direct.cc: In function 'void CommunicationsLog::record_communication(pid_t, CommunicationsLog::Direction, unsigned int, unsigned int, const std::string&) [with T = char]': source/sparse_direct.cc:296: internal compiler error: in cp_expr_size, at cp/cp-objcp-common.c:86 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. W.
Created attachment 7663 [details] Preprocessed sources, not reduced
That's as short as I can get it for now: ---------------------- #include <string> struct Record { unsigned int a, b, c, d, e; std::string description; }; template <typename T> void foobar () { const Record record = {0,0,0,0,0,std::string()}; } template void foobar<int> (); --------------------------- source/a.cc: In function 'void foobar() [with T = int]': source/a.cc:14: instantiated from here source/a.cc:12: warning: unused variable 'record' source/a.cc:12: internal compiler error: in cp_expr_size, at cp/cp-objcp-common.c:86 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. Surprisingly, the number of elements in the structure do make a difference! W.
I have it done 120 lines or so.
Reduced testcase: struct allocator { allocator() throw(); allocator(const allocator& __a); }; struct string { mutable allocator _M_dataplus; string& operator=(const string& __str); }; struct Record { unsigned int a, b, c, d, e; string description; }; void foobar () { const Record record = {0}; } : Search converges between 2004-10-26-161001-trunk (#611) and 2004-11-03-014001-trunk (#612).
The problem is that we are putting the struct in static space: static struct Record C.0 = {.a=0};
We can save one layer of objects: ------------------------- struct S { S(); S(const S&); void operator=(const S&); }; struct X { int a, b, c, d, e; S s; }; void foobar () { X x = {0}; } ---------------------- sandbox/tt> /ices/bangerth/tmp/build-gcc/gcc-install/bin/c++ -c x.cc x.cc: In function 'void foobar()': x.cc:13: internal compiler error: in cp_expr_size, at cp/cp-objcp-common.c:86 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions. W.
This is most likely the same as PR 18865. W.
*** Bug 18865 has been marked as a duplicate of this bug. ***
Mark, the regression appeared with your patch for PR 15172: http://gcc.gnu.org/ml/gcc-cvs/2004-11/msg00002.html The example still compiles fine on the 3.4 branch although you applied the patch there, too. Could you please have a look?
I'm not sure how to fix this yet. The C++ front end is generating what looks to me to perfectly reasonable code. Then, gimplify_init_constructor decides that it wants to create a temporary variable of type X. It's never, ever correct for the middle end to create a variable of type with a copy constructor, and the assert catches this error later. The middle end is transforming: x = { 0 } into: static const X temp = { 0 }; x = temp; That's wrong, if X has a constructor or destructor. One solution would be to say that an object of a type for which this is invalid cannot be initialized with a CONSTRUCTOR, and have the front end lower away the CONSTRUCTOR. But, that would be a change from longstanding precedent, and a CONSTRUCTOR seems the right way to represent this. Then again, my change, to split out nonconstant inits, might result in initializations taking place in an order not allowed by the standard. So, more thought is required.
Upon further reflection, I don't see a problem with what the gimplifier is doing, because it does not actually try to construct the S component in the temporary variable.
Subject: Bug 18793 CVSROOT: /cvs/gcc Module name: gcc Changes by: mmitchel@gcc.gnu.org 2004-12-14 19:38:26 Modified files: gcc/testsuite : ChangeLog gcc/cp : ChangeLog cp-objcp-common.c Added files: gcc/testsuite/g++.dg/init: aggr3.C Log message: PR c++/18793 * cp-objcp-common.c (cp_expr_size): Loosen assertion. PR c++/18793 * g++.dg/init/aggr3.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.4754&r2=1.4755 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/init/aggr3.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4533&r2=1.4534 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cp-objcp-common.c.diff?cvsroot=gcc&r1=1.4&r2=1.5
Fixed in GCC 4.0.