>Submitter-Id:  net
>Originator:    Clifford Heath
>Organization:  ManageSoft
>Confidential:  no
>Synopsis:      g++ ICE in cp_expr_size expanding template with inline
assembly
>Severity:      critical
>Priority:      medium
>Category:      g++
>Class:         ice-on-legal-code
>Release:       4.0.3 20060128 (prerelease) (Debian 4.0.2-8) (Debian
testing/uns
table)
>Environment:
System: Linux debian 2.6.12.3 #1 SMP Sun Sep 11 10:20:54 EST 2005 i686
GNU/Linux
Architecture: i686

        <machine, os, target, libraries (multiple lines)>
host: i486-pc-linux-gnu
build: i486-pc-linux-gnu
target: i486-pc-linux-gnu
configured with: ../src/configure -v
--enable-languages=c,c++,java,f95,objc,ada,
treelang --prefix=/usr --enable-shared --with-system-zlib
--libexecdir=/usr/lib
--without-included-gettext --enable-threads=posix --enable-nls
--program-suffix=
-4.0 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug
--enabl
e-java-awt=gtk-default --enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.4
.2-gcj-4.0-1.4.2.0/jre --enable-mpfr --disable-werror --with-tune=i686
--enable-
checking=release i486-linux-gnu
>Description:
        ICE in this version of G++, previous version worked (not sure
which),
        when compiling a method of a class that subclasses a template
that
        contains inline assembly code (used for atomic instructions).
>How-To-Repeat:

template <class T>
class AtomicM
{
public:
        AtomicM(T i = T()) : val(i) { }
        AtomicM(const AtomicM& from) : val(from.val) { }
        AtomicM& operator=(const AtomicM& from)
                { exchange(from.val); return *this; }

        inline T exchangeCmp(T e, T comparand) volatile
        {
                register int eax asm("eax") = comparand;
                __asm__ __volatile__(
                        "lock; cmpxchg %2,%0"
                                : "+m" (val)
                                , "+a" (eax)
                                : "q" (e)
                                : "cc"
                );
                return (T)eax;
        }

protected:
        volatile T val;
};

class LatchC
        : private AtomicM<int>
{
public:
        inline void latch(int i) volatile
        {
                while (exchangeCmp(i, 0) != 0)
                        yield(1);
        }
        void enter();
private:
        static void yield(int ms);
};

void
LatchC::enter()
{
        latch(1);
}

Reply via email to