aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/warn-overloaded-virtual.cpp
blob: 6204826192d7b24747b3d6fe990156254645ea9a (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
153
154
155
156
157
158
// RUN: %clang_cc1 -fsyntax-only -Woverloaded-virtual -verify %s

struct B1 {
  virtual void foo(int); // expected-note {{declared here}}
  virtual void foo(); // expected-note {{declared here}}
};

struct S1 : public B1 {
  void foo(float); // expected-warning {{hides overloaded virtual functions}}
};

struct S2 : public B1 {
  void foo(); // expected-note {{declared here}}
};

struct B2 {
  virtual void foo(void*); // expected-note {{declared here}}
};

struct MS1 : public S2, public B2 {
   virtual void foo(int); // expected-warning {{hides overloaded virtual functions}}
};

struct B3 {
  virtual void foo(int);
  virtual void foo();
};

struct S3 : public B3 {
  using B3::foo;
  void foo(float);
};

struct B4 {
  virtual void foo();
};

struct S4 : public B4 {
  void foo(float);
  void foo();
};

namespace PR9182 {
struct Base {
  virtual void foo(int);
};

void Base::foo(int) { }

struct Derived : public Base {
  virtual void foo(int);
  void foo(int, int);
};
}

namespace PR9396 {
class A {
public:
  virtual void f(int) {}
};

class B : public A {
public:
  static void f() {}
};
}

namespace ThreeLayer {
struct A {
  virtual void f();
};

struct B: A {
  void f();
  void f(int);
};

struct C: B {
  void f(int);
  using A::f;
};
}

namespace UnbalancedVirtual {
struct Base {
  virtual void func();
};

struct Derived1: virtual Base {
  virtual void func();
};

struct Derived2: virtual Base {
};

struct MostDerived: Derived1, Derived2 {
  void func(int);
  void func();
};
}

namespace UnbalancedVirtual2 {
struct Base {
  virtual void func();
};

struct Derived1: virtual Base {
  virtual void func();
};

struct Derived2: virtual Base {
};

struct Derived3: Derived1 {
  virtual void func();
};

struct MostDerived: Derived3, Derived2 {
  void func(int);
  void func();
};
}

namespace {
  class A {
    virtual int foo(bool) const;
    // expected-note@-1{{type mismatch at 1st parameter ('bool' vs 'int')}}
    virtual int foo(int, int) const;
    // expected-note@-1{{different number of parameters (2 vs 1)}}
    virtual int foo(int*) const;
    // expected-note@-1{{type mismatch at 1st parameter ('int *' vs 'int')}}
    virtual int foo(int) volatile;
    // expected-note@-1{{different qualifiers (volatile vs const)}}
  };

  class B : public A {
    virtual int foo(int) const;
    // expected-warning@-1{{hides overloaded virtual functions}}
  };
}

namespace {
struct base {
  void f(char) {}
};

struct derived : base {
  void f(int) {}
};

void foo(derived &d) {
  d.f('1'); // FIXME: this should warn about calling (anonymous namespace)::derived::f(int)
            // instead of (anonymous namespace)::base::f(char).
            // Note: this should be under a new diagnostic flag and eventually moved to a
            // new test case since it's not strictly related to virtual functions.
  d.f(12);  // This should not warn.
}
}