From mboxrd@z Thu Jan 1 00:00:00 1970 From: smacdonald@seimac.com To: gcc-gnats@gcc.gnu.org Subject: c++/4377: more errors with multiple non-type template parameters Date: Sat, 22 Sep 2001 11:56:00 -0000 Message-id: <20010922185421.1496.qmail@sourceware.cygnus.com> X-SW-Source: 2001-09/msg00464.html List-Id: >Number: 4377 >Category: c++ >Synopsis: more errors with multiple non-type template parameters >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: ice-on-legal-code >Submitter-Id: net >Arrival-Date: Sat Sep 22 11:56:00 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Scott MacDonald >Release: gcc-3.1 snapshot of 2001-09-17 >Organization: >Environment: Red Hat Linux 7.1, Intel >Description: This problem is an extension of bug #3911. The code posted in that report compiles fine, but the addition of another operator causes an Internal error: Segmentation fault . The code works fine using gcc 2.95.3 and using Comeau Computing's online compiler (4.2.45.2). This was the result of a compile of test-1.cc (code below). > g++ test-1.cc test-1.cc: In function `int main()': test-1.cc:28: Internal error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See for instructions. For a bit more information if you add a specialization of the template with inline friends (not nice but legal and necessary on older gcc versions) the compile no longer gets an internal error, but complains about virtual functions being abstract. (code test-2.cc is below) > g++ test-2.cc test-2.cc:33: invalid return type for function `unit<0, 0> operator/(const unit<0, 0>&, const unit<0, 0>&)' test-2.cc:33: because the following virtual functions are abstract: test-2.cc:30: unit<0, 0> operator*(const unit<0, 0>&, const unit<0, 0>&) test-2.cc:46: confused by earlier errors, bailing out The above test also compiles find on both g++ 2.95.3 and Comeau Computing (4.2.45.2). Scott MacDonald code: ========================================== test-1.cc template < int I1, int I2 > class unit { public: unit() {} unit( const unit& ) {} template< int Q1, int Q2 > unit< I1 + Q1, I2 + Q2 > operator * ( const unit< Q1, Q2 >& rhs ) const { return unit< I1 + Q1, I2 + Q2 >(); } template< int Q1, int Q2 > unit< I1 - Q1, I2 - Q2 > operator / ( const unit< Q1, Q2 >& rhs ) const { return unit< I1 - Q1, I2 - Q2 >(); } }; int main() { const unit<1,0> u1; const unit<2,0> u2; unit<-1,0> u3( u1 / u2 ); unit< 3,0> u4( u1 * u2 ); } ====================================== test-2.cc template < int I1, int I2 > class unit { public: typedef unit my_type; unit() {} unit( const unit& ) {} template< int Q1, int Q2 > unit< I1 + Q1, I2 + Q2 > operator * ( const unit< Q1, Q2 >& rhs ) const { return unit< I1 + Q1, I2 + Q2 >(); } template< int Q1, int Q2 > unit< I1 - Q1, I2 - Q2 > operator / ( const unit< Q1, Q2 >& rhs ) const { return unit< I1 - Q1, I2 - Q2 >(); } }; // specialization added to first test // template <> class unit<0,0> { public: typedef unit<0,0> my_type; unit() {} friend unit<0,0> operator*( const unit<0,0>& lhs, const unit<0,0>& rhs ) { return unit<0,0>(); } friend unit<0,0> operator/( const unit<0,0>& lhs, const unit<0,0>& rhs ) { return unit<0,0>(); } }; int main() { const unit<1,0> u1; const unit<2,0> u2; unit<-1,0> u3( u1 / u2 ); unit< 3,0> u4( u1 * u2 ); } >How-To-Repeat: g++ test-1.cc >Fix: >Release-Note: >Audit-Trail: >Unformatted: