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=18953

Reply via email to