extern double sqrt (double __x) throw (); namespace ns { using ::sqrt; template<typename _Tp> class C { public: C(const _Tp& = _Tp(), const _Tp & = _Tp()); const _Tp& r() const; const _Tp& i() const; private: _Tp _M_r; _Tp _M_i; };
template<typename _Tp> inline const _Tp& C<_Tp>::r() const { return _M_r; } template<typename _Tp> inline const _Tp& C<_Tp>::i() const { return _M_i; } template<typename _Tp> inline C<_Tp>::C(const _Tp& __r, const _Tp& __i) : _M_r(__r), _M_i(__i) { } template<typename _Tp> _Tp foo(const C<_Tp>&); template<typename _Tp> _Tp bar(const C<_Tp>&); template<typename _Tp> inline _Tp bar(const C<_Tp>& __z) { _Tp __x = __z.r(); _Tp __y = __z.i(); const _Tp __s = __builtin_fabs(__x); __x /= __s; __y /= __s; return __s * sqrt(__x * __x + __y * __y); } template<typename _Tp> _Tp foo(const C<_Tp>& __z) { _Tp __x = __z.r(); _Tp __t = sqrt(ns::bar(__z)); return __t; } } ns::C<double> z1(1.0/0.0, 0.0); double z2; int main() { z2 = ns::foo(z1); return 0; } at -O1, -O2 or -O3 is compiled into an endless loop. The bug seems to be that expand_errno_check expands arguments once again and they haven't been save_expr'ed. -- Summary: Invalid code generated by expand_errno_check Product: gcc Version: 3.4.3 Status: UNCONFIRMED Severity: normal Priority: P2 Component: middle-end AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jakub at gcc dot gnu dot org CC: gcc-bugs at gcc dot gnu dot org GCC target triplet: x86_64-redhat-linux, i386-redhat-linux http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18951