When running a program that makes heavy use of expression templates, it works
fine with any -O option.  However, if no -O option is used, then it segfaults.

Note that if the expression used is changed to something like arg + arg, then it
doesn't crash but gives wrong results if no -O option is specified.

typedef unsigned int size_t;

struct AddOp
{
        template<class I1, class I2> static inline float
        call(size_t i, const I1& i1, const I2& i2) {return i1[i] + i2[i];}
};

struct MultOp
{
        template<class I1, class I2> static inline float
        call(size_t i, const I1& i1, const I2& i2) {return i1[i] * i2[i];}
};

class Expr
{
        float data;
public:
        Expr(float arg_data) : data(arg_data) {}

        float
        operator[](size_t i) const {return data;}

};

template<class I1, class I2, class Op>
class Expr3
{
        const I1& i1;
        const I2& i2;
public:
        Expr3(const I1& ai1, const I2& ai2)
         : i1(ai1), i2(ai2)
        {
        }

        float
        operator[](size_t i) const
        {
                return Op::call(i, i1, i2);
        }

        template<class E>
        Expr3<Expr3, E, AddOp>
        operator+(const E& e) const
        {
                return Expr3<Expr3, E, AddOp>(*this, e);
        }

};

struct Vec4
{
        Vec4(float all)
         : x(all), y(all), z(all), w(all)
        {
        }

        Vec4(float ax, float ay, float az, float aw = 1)
         : x(ax), y(ay), z(az), w(aw)
        {
        }

        float x, y, z, w;

        float
        operator[](size_t i) const
        {
                switch(i) {
                case 0: return x;
                case 1: return y;
                case 2: return z;
                case 3: return w;
                default: return 0xdeadbeef;
                }
        }

        const Vec4&
        operator=(float arg)
        {
                x = y = z = w = arg; return *this;
        }

        Expr3<Vec4, Expr, MultOp>
        operator*(float e) const
        {
                return Expr3<Vec4, Expr, MultOp>(*this, Expr(e));
        }

        template<class E>
        const Vec4&
        operator=(const E& e)
        {
                x = e[0]; y = e[1]; z = e[2]; w = e[3]; return *this;
        }
};

template<class T>
Expr3<Expr3<Vec4, Expr, MultOp>, Expr3<Vec4, Expr, MultOp>, AddOp>
dostuff(const T& arg)
{
        return (arg * 0.9999f) + (arg * 0.00001f);
}

int
main()
{
        const float ARG1 = 3.40282347e+38f;

        Vec4 v1(ARG1), v2(ARG1);

        v2 = dostuff(v1);
}

-- 
           Summary: Heavily template-expression using program crashes on -O0
                    but not on -O1
           Product: gcc
           Version: 3.4.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ayqazi at yahoo dot co dot uk
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i686-pc-linux
  GCC host triplet: i686-pc-linux
GCC target triplet: i686-pc-linux


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18415

Reply via email to