------- Comment #3 from jakub at gcc dot gnu dot org 2008-06-02 17:23 ------- Smaller testcase for -m32 -Os -fpic -fasynchronous-unwind-tables -fno-inline:
extern "C" { struct FILE; extern FILE *stderr; extern int fprintf (FILE *, const char *, ...); struct R { int r1; unsigned short r2[1]; }; int bar1 (unsigned short *, int, short) throw (); void bar2 (R *) throw (); void bar3 (R **, const unsigned short *, int) throw (); void bar4 (R **, const char *) throw (); void bar5 (R **, R *) throw (); void bar6 (R **, R *, R *) throw (); } struct S { R *s; struct T { }; S (R *x, T *) { s = x; } ~S () { bar2 (s); } S &operator= (const S &x); S &operator+= (const S &x); S sfn1 (const S &x) const; friend S operator+ (const S &x1, const S &x2); static S sfn2 (int i) { unsigned short q[33]; R *p = 0; bar3 (&p, q, bar1 (q, i, 10)); return S (p, (T *) 0); } static S sfn3 (const char *x) { R *p = 0; bar4 (&p, x); return S (p, (T *) 0); } }; struct U { }; template <class C> inline unsigned char operator >>= (const U &, C &); struct V; struct W { V *w; unsigned char is () const; }; template <class T> struct X : public W { static T *xfn1 (V *p); inline ~X (); X (); X (const W &rRef); T *operator -> () const; }; struct E { E (); E (const S &, const X <V> &); E (E const &); ~E (); E &operator = (E const &); S e; X <V> f; }; struct V { virtual void release () throw () = 0; }; template <class T> X <T>::~X () { if (w) w->release (); } struct Y { virtual U yfn1 (const S &aName) = 0; }; struct Z; X <V> baz1 (const S &) throw (E); X <Z> baz2 (const X <Z> &xStream) throw (E); X <Z> foo () throw () { X <Z> xResult; X <Y> xNameContainer; try { xNameContainer = X <Y> (baz1 (S::sfn3 ("com.sun.star.embed.OLESimpleStorage"))); } catch (E &) { } if (xNameContainer.is ()) { for (int nInd = 0; nInd < 10; nInd++) { S aStreamName = S::sfn3 ("abcd"); aStreamName += S::sfn2 ((int) nInd); X <Z> xCachedCopyStream; try { { fprintf (stderr, "trying %d\n", nInd); } if ((xNameContainer-> yfn1 (aStreamName) >>= xCachedCopyStream)) if (xCachedCopyStream.is ()) { { fprintf (stderr, "still trying %d\n", nInd); } xResult = baz2 (xCachedCopyStream); if (xResult.is ()) break; } { fprintf (stderr, "success on %d\n", nInd); } } catch (...) { fprintf (stderr, "failure on %d\n", nInd); } } } return xResult; } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36419