1 // PR optimization/12965
2 // Origin: <qboosh@pld-linux.org>
3 // Reduced testcase: Falk Hueffner <falk@debian.org>
4 
5 // This ICEd on Alpha because the reload pass emitted save/restore
6 // insns around a no-return call.
7 
8 // { dg-do compile }
9 // { dg-options "-O2" }
10 
11 template <typename _Alloc> class allocator;
12 template <class _CharT> struct char_traits;
13 template <typename _CharT,
14 	  typename _Traits = char_traits<_CharT>,
15 	  typename _Alloc = allocator<_CharT> >
16 class basic_string;
17 typedef basic_string<char> string;
18 
__exchange_and_add(volatile int * __mem,int __val)19 static inline int __exchange_and_add(volatile int * __mem, int __val) {
20     int __result;
21     asm("" : "=&r"(__result));
22     return __result;
23 }
24 
25 template<typename _Tp> struct allocator {
throwallocator26     allocator() throw() { }
throwallocator27     allocator(const allocator &) throw() {}
28 };
29 
30 template<typename _CharT, typename _Traits, typename _Alloc>
31 struct basic_string {
32     typedef _Alloc allocator_type;
33     struct _Rep {
34 	int _M_references;
_M_disposebasic_string::_Rep35 	void _M_dispose(const _Alloc & __a) {
36 	    if (__exchange_and_add(&_M_references, -1) <= 0)
37 		_M_destroy(__a);
38 	} void _M_destroy(const _Alloc &) throw();
39     };
40     struct _Alloc_hider : _Alloc {
41 	_CharT *_M_p;
42     };
43     mutable _Alloc_hider _M_dataplus;
_M_databasic_string44     _CharT *_M_data() const { return _M_dataplus._M_p; }
_M_repbasic_string45     _Rep *_M_rep() const {
46 	return &((reinterpret_cast<_Rep *>(_M_data()))[-1]);
47     }
48     basic_string();
49     basic_string(const _CharT * __s, const _Alloc & __a = _Alloc());
~basic_stringbasic_string50     ~basic_string() {
51 	_M_rep()->_M_dispose(this->get_allocator());
52     }
get_allocatorbasic_string53     allocator_type get_allocator() const { return _M_dataplus; }
54 };
55 
56 struct Egeneric {
57     void stack(const string & passage, const string & message = "") { }
58 };
59 
60 struct infinint {
61     void detruit() throw(Egeneric);
62     template<class T> void infinint_from(T a) throw(Egeneric);
throwinfinint63     infinint(long a = 0) throw(Egeneric) {
64 	try {
65 	    infinint_from(a);
66 	} catch(Egeneric& e) {
67 	    e.stack("infinint::infinint", "long");
68 	}
69     }
throwinfinint70     ~infinint() throw(Egeneric) {
71 	try {
72 	    detruit();
73 	} catch(Egeneric& e) { }
74     }
75 };
76 
77 struct inode {
78     string x;
79     infinint a, c;
80     infinint ea_offset;
81     inode();
82 };
83 
inode()84 inode::inode()
85 {
86     ea_offset = 0;
87 }
88