1// { dg-do assemble  }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class ref_counted
20{
21
22protected:
23        ref_counted( void ) : _count( 0 ) {}
24
25public:
26
27        unsigned int add_ref( void ) { return ++_count; }
28        unsigned int release( void ) { return --_count; }
29        unsigned int count( void ) const { return _count; }
30
31
32protected:
33        unsigned int _count;
34};
35
36
37
38
39
40template < class T >
41class ref_ptr
42{
43
44public:
45        ref_ptr( T* ptr = 0 ) : _ptr( ptr )
46        {
47                add_ref();
48        }
49
50        ref_ptr( const ref_ptr & rptr ) : _ptr( rptr.get() )
51        {
52                add_ref();
53        }
54
55        ~ref_ptr( void ) { release(); }
56
57
58        T* get( void ) const { return _ptr; }
59        T* operator->( void ) const { return get(); }
60        T& operator*( void ) const { return *get(); }
61
62        bool operator!( void ) const { return get() == 0; }
63        bool operator==( const ref_ptr & rptr ) const { return *get() == *rptr;
64}
65        bool operator<( const ref_ptr & rptr ) const { return *get() < *rptr; }
66
67
68        bool operator==( T* ptr ) const { return *get() == *ptr; }
69        bool operator<( T* ptr ) const { return *get() < *ptr; }
70
71        const ref_ptr & operator=( const ref_ptr & rptr )
72        {
73                release();
74                _ptr = rptr.get();
75                add_ref();
76
77                return *this;
78        }
79
80       T* operator=( T* ptr )
81       {
82         release();
83         _ptr = ptr;
84         add_ref();
85
86         return _ptr;
87       }
88
89protected:
90        void add_ref( void )
91        {
92                if( _ptr )
93                        _ptr->add_ref();
94        }
95
96        void release( void )
97        {
98                if( _ptr && 0 == _ptr->release() )
99                {
100                        delete _ptr;
101                        _ptr = 0;
102                }
103        }
104
105
106protected:
107        T *     _ptr;
108};
109
110
111template< class T >
112bool operator==( T* ptr, const ref_ptr< T > & rptr )
113{
114        return *ptr == *rptr;
115}
116
117template< class T >
118bool operator<( T* ptr, const ref_ptr< T > & rptr )
119{
120        return *ptr < *rptr;
121}
122
123
124
125class Baz : public ref_counted {
126  int dummy;
127};
128
129
130class Bar;
131
132int main() {
133  ref_ptr<Baz> foo;
134  static_cast<Bar *> (foo)->DoSomething;  //{ dg-error "" } invalid cast
135}
136