aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/virtual-override.cpp
blob: c18a77f036bb65b487eadd983475671838d65ad0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// RUN: clang-cc -fsyntax-only -faccess-control -verify %s
namespace T1 {

class A {
  virtual int f(); // expected-note{{overridden virtual function is here}}
};

class B : A {
  virtual void f(); // expected-error{{virtual function 'f' has a different return type ('void') than the function it overrides (which has return type 'int')}}
};

}

namespace T2 {

struct a { };
struct b { };
  
class A {
  virtual a* f(); // expected-note{{overridden virtual function is here}}
};

class B : A {
  virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides ('struct T2::b *' is not derived from 'struct T2::a *')}}
};

}

namespace T3 {

struct a { };
struct b : private a { }; // expected-note{{'private' inheritance specifier here}}
  
class A {
  virtual a* f(); // expected-note{{overridden virtual function is here}}
};

class B : A {
  virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides (conversion from 'struct T3::b' to inaccessible base class 'struct T3::a')}}
};

}

namespace T4 {

struct a { };
struct a1 : a { };
struct b : a, a1 { };
  
class A {
  virtual a* f(); // expected-note{{overridden virtual function is here}}
};

class B : A {
  virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides (ambiguous conversion from derived class 'struct T4::b' to base class 'struct T4::a':\n\
    struct T4::b -> struct T4::a\n\
    struct T4::b -> struct T4::a1 -> struct T4::a)}}
};

}

namespace T5 {
  
struct a { };

class A {
  virtual a* const f(); 
  virtual a* const g(); // expected-note{{overridden virtual function is here}}
};

class B : A {
  virtual a* const f(); 
  virtual a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides ('struct T5::a *' has different qualifiers than 'struct T5::a *const')}}
};

}

namespace T6 {
  
struct a { };

class A {
  virtual const a* f(); 
  virtual a* g(); // expected-note{{overridden virtual function is here}}
};

class B : A {
  virtual a* f(); 
  virtual const a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides (class type 'struct T6::a const *' is more qualified than class type 'struct T6::a *'}}
};

}

namespace T7 {
  struct a { };
  struct b { };

  class A {
    a* f();
  };

  class B : A {
    virtual b* f();
  };
}

// PR5656
class X0 {
  virtual void f0();
};
class X1 : public X0 {
  void f0() = 0;
};

template <typename Base>
struct Foo : Base { 
  void f(int) = 0; // expected-error{{not virtual and cannot be declared pure}}
};

struct Base1 { virtual void f(int); };
struct Base2 { };

void test() {
  (void)sizeof(Foo<Base1>);
  (void)sizeof(Foo<Base2>); // expected-note{{instantiation}}
}

template<typename Base>
struct Foo2 : Base {
  template<typename T> int f(T);
};

void test2() {
  Foo2<Base1> f1;
  Foo2<Base2> f2;
  f1.f(17);
  f2.f(17);
};

struct Foo3 {
  virtual void f(int) = 0; // expected-note{{pure virtual function}}
};

template<typename T>
struct Bar3 : Foo3 {
  void f(T);
};

void test3() {
  Bar3<int> b3i; // okay
  Bar3<float> b3f; // expected-error{{is an abstract class}}
}